Подтвердить что ты не робот

Простой пример UDP для отправки и получения данных из одного и того же сокета

По какой-то причине мне трудно отправлять и получать данные из одного и того же сокета. В любом случае, это мой клиентский код:

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

В принципе, я хочу создать протокол, в котором я отправляю пакет udp, а затем ожидаю ответа. Как и HTTP-протокол для каждого запроса, есть ответ. Этот код работает, если сервер находится на другом компьютере. Возможно, в этом случае сервер и клиент находятся на одном компьютере.

Вот сервер:

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          
}

Изменить

причина, по которой я не могу использовать tcp, заключается в том, что иногда клиент находится за NAT (маршрутизатор), и проще пробить UDP, чем TCP.


Решение:

благодаря ответу markmnl вот мой код:

Сервер:

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
}

Клиентский код:

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();
4b9b3361

Ответ 1

(я полагаю, вы знаете, что использование UDP (User Datagram Protocol) не гарантирует доставку, проверяет наличие дубликатов и контроль перегрузок и просто ответит на ваш вопрос).

На вашем сервере эта строка:

var data = udpServer.Receive(ref groupEP);

переназначает groupEP от того, что вы получили к адресу, в котором вы получаете что-то.

Эта строка:

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

Не будет работать, так как вы не указали, кому отправлять данные. (Он работает на вашем клиенте, потому что вы вызвали соединение, которое означает, что отправка всегда будет отправляться в конечную точку, к которой вы подключились, конечно, мы не хотим, чтобы на сервере, поскольку у нас могло быть много клиентов). Я бы:

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          
}

Также, если у вас есть сервер и клиент на том же компьютере, вы должны иметь их на разных портах.