在.NET中UDP的工作原理是什么?

3

我被告知UDP是一种无连接协议,这意味着您无法确定数据包是否能够到达目的地。

为什么执行以下操作:

var dataToSend = new byte[]{1};
UdpClient client = new UdpClient();
client.Send(dataToSend,1,"192.168.0.45", 1234);

变量LocalEndpoint初始化:

enter image description here

请指正,我认为变量LocalEndpoint是由路由器初始化的。原因是每当服务器(192.168.0.45)接收数据并回复时,我看到数据通过回复中的62446端口发送。

我的问题是,如果我使用UDP协议,为什么会从路由器得到响应?如果我从路由器得到响应,那就不是UDP,或者我对UDP的理解有误。我认为端口号不会随机选择。如果我已经在路由器上配置了端口转发到某台其他计算机的62446端口,则我的程序将无法工作。


以下是客户端代码:

string ipOfServer = "192.168.0.45";
int portServerIsListeningOn = 1234;

// send data to server
Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint sending_end_point = new IPEndPoint(IPAddress.Parse(ipOfServer), portServerIsListeningOn);
sending_socket.SendTo(Encoding.ASCII.GetBytes("Test"), sending_end_point);

// after I send data localendpoint gets initialized! and the server always respond through that port!

// get info
var port = sending_socket.LocalEndPoint.ToString().Split(':')[1];

// now wait for server to send data back
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, int.Parse(port));
byte[] buffer = new byte[1024];
sending_socket.Receive(buffer); // <----- keeps waiting in here :(

这是服务器端代码:

// wait for client to send data
UdpClient listener = new UdpClient(11000);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 11000);        
byte[] receive_byte_array = listener.Receive(ref groupEP);
listener.Connect(groupEP);

// reply
byte[] dataToSend = new byte[] { 1, 2, 3, 4, 5 };
listener.Send(dataToSend, dataToSend.Length);

“无连接”并不意味着“你不能确定数据包是否到达目的地”。它意味着没有建立和拆除阶段,而且你甚至不知道接收者是否存在。即使在TCP中,除非同行应用程序确认了它们,否则你也无法确定数据包是否已到达目的地。 - user207421
1个回答

3
绑定操作返回的是 LocalEndPoint 属性中包含的信息,而不是路由器的信息:
这段摘录来自于 MSDN

LocalEndPoint 属性获取一个 EndPoint,其中包含了 Socket 绑定的本地 IP 地址和端口号。在检索任何信息之前,您必须将此 EndPoint 强制转换为 IPEndPoint。然后,您可以调用 IPEndPoint.Address 方法来检索本地 IPAddress,并调用 IPEndPoint.Port 方法来检索本地端口号。

通常在对 Bind 方法 进行调用之后会设置 LocalEndPoint 属性。如果允许系统为您的套接字分配本地 IP 地址和端口号,则 LocalEndPoint 属性将在第一次 I/O 操作之后设置。对于面向连接的协议,第一次 I/O 操作将是对 Connect 或 Accept 方法的调用。对于无连接协议,第一次 I/O 操作将是任何发送或接收调用。

但是你的理解是正确的,UDP是一种“发送并忘记”的数据传输方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接