简单的UDP示例,用于从同一个套接字发送和接收数据

Ton*_*Nam 41 c# 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
Run Code Online (Sandbox Code Playgroud)

基本上我想创建一个协议,我发送一个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          
}
Run Code Online (Sandbox Code Playgroud)

编辑

我不能使用tcp的原因是因为有时客户端在NAT(路由器)后面,并且比TCP更容易进行UDP打孔.


解:

感谢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
}
Run Code Online (Sandbox Code Playgroud)

客户代码:

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();
Run Code Online (Sandbox Code Playgroud)

mar*_*mnl 25

(我认为您知道使用UDP(用户数据报协议)不保证传送,检查重复和拥塞控制,只会回答您的问题).

在你的服务器这一行:

var data = udpServer.Receive(ref groupEP);
Run Code Online (Sandbox Code Playgroud)

groupEP从您所拥有的地址重新分配您收到的地址.

这一行:

udpServer.Send(new byte[] { 1 }, 1); 
Run Code Online (Sandbox Code Playgroud)

由于您尚未指定将数据发送到谁,因此无法工作.(它适用于您的客户端,因为您调用了连接,这意味着发送将始终发送到您连接的端点,当然我们不希望在服务器上,因为我们可以拥有许多客户端).我会:

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          
}
Run Code Online (Sandbox Code Playgroud)

此外,如果您在同一台计算机上有服务器和客户端,则应将它们放在不同的端口上.

  • 呃,这不是你知道的UDP,这是一个UDP之上的协议.我碰巧知道的很好,我已经在UDP之上编写协议以实现可靠性. (4认同)
  • @ArteS 如果您打算特别频繁地再次使用“UdpClient”,我不会使用“using” - 每次都进行处理和重新创建会很浪费。因此,不幸的是,无法使用“使用有用的糖”来为您处理处置,并且必须自己小心处理。 (2认同)