web-dev-qa-db-fra.com

Exemple UDP simple pour envoyer et recevoir des données du même socket

Pour une raison quelconque, j'ai du mal à envoyer et recevoir des données à partir du même socket. En tout cas voici mon code client:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening (testing localy)
client.Connect(ep); 

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);  // Exception: An existing connection was forcibly closed by the remote Host

En gros, je veux créer un protocole dans lequel j'envoie un paquet udp, puis j'attends une réponse. Tout comme le protocole HTTP pour chaque requête, il y a une réponse. Ce code fonctionne si le serveur est sur un serveur différent. ordinateur. Il peut arriver que le serveur et le client se trouvent sur le même ordinateur.

Voici le serveur:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var groupEP = new IPEndPoint(IPAddress.Any, 11000); // listen on any port
    var data = udpServer.Receive(ref groupEP);
    udpServer.Send(new byte[] { 1 }, 1); // if data is received reply letting the client know that we got his data          
}

Modifier

la raison pour laquelle je ne peux pas utiliser tcp est que parfois le client est derrière un NAT (routeur) et qu'il est plus simple de faire de la perforation UDP que TCP.


Solution:

merci à markmnl réponse voici mon code:

Serveur:

UdpClient udpServer = new UdpClient(11000);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000); 
    var data = udpServer.Receive(ref remoteEP); // listen on port 11000
    Console.Write("receive data from " + remoteEP.ToString());
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // reply back
}

Code client:

var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 11000); // endpoint where server is listening
client.Connect(ep);

// send data
client.Send(new byte[] { 1, 2, 3, 4, 5 }, 5);

// then receive data
var receivedData = client.Receive(ref ep);

Console.Write("receive data from " + ep.ToString());

Console.Read();
39
Tono Nam

(Je présume que vous savez qu'utiliser UDP (User Datagram Protocol) ne garantit pas la livraison, recherche les doublons et le contrôle de la congestion et répondra simplement à votre question).

Sur votre serveur cette ligne:

var data = udpServer.Receive(ref groupEP);

réaffecte groupEP de ce que vous aviez à une adresse sur laquelle vous recevez quelque chose.

Cette ligne:

udpServer.Send(new byte[] { 1 }, 1); 

Ne fonctionnera pas car vous n'avez pas spécifié à qui envoyer les données. (Cela fonctionne sur votre client parce que vous avez appelé connect, ce qui signifie que send sera toujours envoyé au point de terminaison auquel vous êtes connecté, bien sûr, nous ne voulons pas de cela sur le serveur car nous pourrions avoir de nombreux clients). Je voudrais:

UdpClient udpServer = new UdpClient(UDP_LISTEN_PORT);

while (true)
{
    var remoteEP = new IPEndPoint(IPAddress.Any, 11000);
    var data = udpServer.Receive(ref remoteEP);
    udpServer.Send(new byte[] { 1 }, 1, remoteEP); // if data is received reply letting the client know that we got his data          
}

De plus, si vous avez un serveur et un client sur le même ordinateur, vous devez les avoir sur des ports différents.

25
markmnl

Je vais essayer de rester bref, je l'ai fait this il y a quelques mois pour un jeu que je tentais de créer, il établit une connexion UDP "Client-Serveur" qui agit comme TCP peut envoyer (message) (message + objet) en utilisant ceci. J'ai fait quelques essais avec et cela fonctionne très bien, n'hésitez pas à le modifier si nécessaire.

2
Creţu Cosmin