Frage

Ist es möglich, zwei separate Programme bekommen auf demselben Computer zu kommunizieren (one-way nur) über UDP durch localhost / 127 ... durch den gleichen Port # teilen?

Wir arbeiten an einem Studentenprojekt, in dem wir UDP-Pakete enthalten eine Telemetrieverbindung zwischen zwei Computern senden müssen. Das Programm, das diese Pakete erzeugt ist proprietär, aber ich bin auf dem Empfänger-Programm selbst mit C # unter Verwendung von System.Net.Sockets.UdpClient und System.Net.IPEndPoint .

Das funktioniert gut, während unsere Gruppe Sitzungen, wenn wir mehrere Computer angeschlossen haben, auf dem wir die beiden Programme separat ausgeführt werden können. Aber es ist nicht sehr nützlich, wenn ich zu Hause bin und versuche, sich auf dem Telemetrieverarbeitungsprogramm zu erweitern, wie ich nur einen Computer habe (Ich brauche einen Feed für die Prüfung des Verarbeitungsprogrammes). Ich kann nicht das Programm auf einem der Schule Computer installieren entweder.

Wenn ich versuche, beiden Programme auf meinem Computer zur gleichen Zeit ausgeführt wird (beginnend mein Programm reicht) erhalte ich eine Socket sagen, dass nur eine einzige Verwendung von jedem Port ist normal erlaubt. Das führt mich zu glauben, es muss ein Weg geben, um den Port zu teilen (obwohl es sinnvoll ist, dass nur ein einziges Programm-Port auf einem Computer zu einem beliebigen Zeitpunkt verwenden kann, ich habe keine Probleme laufen mehrere Internet-Browser zur gleichen Zeit (und ich nehme an, sie verwenden den Port 80 für hTTP)).

reedit des EDIT:

sipwiz war richtig, und dank Kalmi für den Zeiger auf UdpClient.Client.Bind (). Zu der Zeit, wir aber erwägen, mit einem anderen Programm, die ähnlichen Paket erzeugt, und mit dem wir in der Lage, Port zu teilen mit auf demselben Computer mit meinem ersten (obwohl naiv) Ansatz mit dem UDP-Client in den Ctor Bindung. Es tut uns mit Ihrer Antwort auf die Markierung aufzuheben, sysrqb.

War es hilfreich?

Lösung

Ich habe nicht erwartet, dies möglich zu sein, aber .. gut .. sipwiz war richtig.

Es kann sehr einfach durchgeführt werden. (Bitte stimmen sipwiz Antwort auf!)

IPEndPoint localpt = new IPEndPoint(IPAddress.Any, 6000);

//Failed try
    try
    {
        var u = new UdpClient(5000);
        u.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        UdpClient u2 = new UdpClient(5000);//KABOOM
        u2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    }
    catch (Exception)
    {
        Console.WriteLine("ERROR! You must call Bind only after setting SocketOptionName.ReuseAddress. \n And you must not pass any parameter to UdpClient's constructor or it will call Bind.");
    }

//This is how you do it (kudos to sipwiz)
    UdpClient udpServer = new UdpClient(localpt); //This is what the proprietary(see question) sender would do (nothing special) 

    //!!! The following 3 lines is what the poster needs...(and the definition of localpt (of course))
    UdpClient udpServer2 = new UdpClient();
    udpServer2.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
    udpServer2.Client.Bind(localpt);

Andere Tipps

Sie können mehrere Male mit der ReuseAddress Socket-Option an einen Port binden.

UdpClient udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

Sie werden die gleiche Option für den UDP-Server-Socket auch festlegen müssen.

Hier ist der vollständige Code aus den Antworten von Tarnay Kálmán und sipwiz:

Der Server-Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace UdpBroadcastTest
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Sender");
            // This constructor arbitrarily assigns the local port number.

            UdpClient udpClient = new UdpClient();
            udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpClient.Connect("localhost", 11000);
            try
            {
                string message = String.Empty;
                do
                {
                    message = Console.ReadLine();
                    // Sends a message to the host to which you have connected.
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(message);

                    udpClient.Send(sendBytes, sendBytes.Length);
                } while (message != String.Empty);

                udpClient.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("Press Any Key to Continue");
            Console.ReadKey();
        }
    }
}

Der Client-Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace UdpReciever
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Receiver");
            // This constructor arbitrarily assigns the local port number.
            UdpClient udpClient = new UdpClient();
            udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 11000));
            try
            {
                //IPEndPoint object will allow us to read datagrams sent from any source.
                IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);

                string message = String.Empty;
                do
                {

                    // Blocks until a message returns on this socket from a remote host.
                    Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);
                    message = Encoding.ASCII.GetString(receiveBytes);

                    // Uses the IPEndPoint object to determine which of these two hosts responded.
                    Console.WriteLine("This is the message you received: " +
                                                 message);
                    //Console.WriteLine("This message was sent from " +
                    //                            RemoteIpEndPoint.Address.ToString() +
                    //                            " on their port number " +
                    //                            RemoteIpEndPoint.Port.ToString());
                }
                while (message != "exit");
                udpClient.Close();
                //udpClientB.Close();

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("Press Any Key to Continue");
            Console.ReadKey();
        }
    }
}

Möglicherweise können Sie mehrere IP-Adressen auf die Netzwerkkarte setzen, oder Loopback, und binden Sie den Server und Client auf verschiedenen IP-Adressen?

oder auch der virtuelle Maschine Ansatz wird auf jeden Fall funktionieren.

Nur ein Programm kann bind mit einem Port zu einem Zeitpunkt. Mehrere Programme können connect an ein Port auf einem anderen System ist, aber die lokal Port Ihre verschiedenen Web-Browser haben sie verpflichtet, nach dem Zufallsprinzip zugewiesen.

Wenn Sie einige hässliche Inter-Prozess-Kommunikation oder Paket tun wollen Schnupfen, gibt es keine Möglichkeit, mehrere Programme an einen Port gebunden zu haben.

Mein Rat: nicht die Portnummer in den UdpClient Konstruktor übergeben. Von der Dokumentation rel="nofollow, (etwas spärlich, ich weiß ...) es sieht so aus, wenn Sie das tun, wird versuchen, die UdpClient zu bind an diesen Port (die, wie sysrqb erwähnt, ist nicht erlaubt). (Wenn Sie dies nicht tun, ich glaube, die UdpClient auf einem zufälligen Port für alle Antworten hören. Sie könnten auch einen Port Sie wissen holen konnte nicht benutzt werden.)

Wenn Sie anrufen Connect () Sie in der Port-Nummer übergeben müssen der Server Hören auf.

binden die beiden Programme, dh der Sender und Empfänger auf den gleichen Port auf den localhost.dats die einfache Antwort.

Ändern Auch Ihr Code, so dass ich in einer IP-Adresse passieren kann ich die gleiche Fehlermeldung wird es scheint, dass Sie nicht auf den gleichen Port binden kann und nur ein Port kann verwendet werden, Hier ist der Beispielcode ich dein Beispiel verwendet und Altered es meine ip von meinem lokalen Rechner zu erfassen ..               IPAddress ipAddress = Dns.Resolve (Dns.GetHostName ()) Address [0].             IPEndPoint ipLocalEndPoint = new IPEndPoint (ipAddress, 11000);

        //IPEndPoint localpt = new IPEndPoint(ipLocalEndPoint);

        UdpClient udpServer = new UdpClient(ipLocalEndPoint);
        udpServer.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
        udpServer.Connect(ipLocalEndPoint);
        UdpClient udpServer2 = new UdpClient();
        udpServer2.Client.SetSocketOption(
            SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

        udpServer2.Client.Bind(ipLocalEndPoint); // <<---------- Exception here

das wird die Ausnahme auf dem Bind () -Methode produzieren .. sorry.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top