这是ReceiveFromAsync()错误吗? [英] Is this ReceiveFromAsync() bug?
问题描述
这是我的第一个问题,我不是英语为母语的人,所以对我(可能)英语不准确表示歉意.
this is my first question and I'm not English native speaker so sorry for my (maybe) inaccurate English.
我正在实现实时网络引擎,并使用Socket.xxxAsync()方法.
I'm implementing real-time network engine and using Socket.xxxAsync() method.
我这样在服务器端制作了一个UDP套接字.
I made a UDP socket at server-side like this.
m_udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_udpSock.Bind(new IPEndPoint(IPAddress.Any, udpPort));
SocketAsyncEventArgs udpRecvArg = new SocketAsyncEventArgs();
udpRecvLoopStart(m_udpSock, udpRecvArg);
(客户端知道udpPort.)
(udpPort is known to client.)
private void udpRecvLoopStart(Socket udpSocket, SocketAsyncEventArgs udpRecvArg)
{
udpRecvArg.AcceptSocket = udpSocket;
byte[] udpRecvBuffer = new byte[NetworkEngineConst.MsgSizeMax];
udpRecvArg.SetBuffer(udpRecvBuffer, 0, udpRecvBuffer.Length);
udpRecvArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
udpRecvArg.Completed += new EventHandler<SocketAsyncEventArgs>(udpRecvArg_Completed);
udpRecv(udpRecvArg);
}
private void udpRecv(SocketAsyncEventArgs udpRecvArg)
{
bool synchronous = false;
try
{
synchronous = !udpRecvArg.AcceptSocket.ReceiveFromAsync(udpRecvArg);
}
catch (Exception e)
{
OnIOError("recvUdp()\n" + e.ToString());
return;
}
if (synchronous)
udpRecvArg_Completed(this, udpRecvArg);
}
完成的事件处理程序是这样:
Completed event handler is this:
void udpRecvArg_Completed(object sender, SocketAsyncEventArgs udpRecvArg)
{
EndPoint udpEp = udpRecvArg.RemoteEndPoint;
string msg = Encoding.UTF8.GetString(udpRecvArg.Buffer, 14, udpRecvArg.BytesTransferred - 14);
Debug.WriteLine(udpEp + " " + msg);
udpRecv(udpRecvArg);
}
(前14个字节是消息前缀,CRC和序列号)
( first 14 bytes are message prefix,CRC and sequence number)
两个(或多个)客户端将UDP数据包发送到服务器.(发送速率为每秒数百个)
And two(or more) clients send UDP packet to server. ( sending rate is hundreds per second )
例如,client1(192.168.0.1:50113)发送"11111111111111111111111111111",client2(192.168.0.1:59368)发送"2".
For example, client1(192.168.0.1:50113) sends "11111111111111111111111111111", client2(192.168.0.1:59368) sends "2".
但有时(并非总是)端点是错误的.日志如下:
But sometimes(not always) endpoint is wrong. log is like below:
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 11111111111111111111111111111 <-错误的部分
192.168.0.1:59368 11111111111111111111111111111 <- wrong part
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:59368 2
192.168.0.1:59368 2
我怀疑数据包错误,但数据包中没有错误(我已通过Wireshark确认)
I doubt packet error, but there was no error in packet(I confirmed with Wireshark)
这是一个错误吗?
(添加)
我尝试了
m_udpSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_udpSock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true);
m_udpSock.Bind(new IPEndPoint(IPAddress.Any, udpPort));
,并将ReceiveFromAsync()替换为ReceiveMessageFromAsync().
and replaced ReceiveFromAsync() with ReceiveMessageFromAsync().
但是SocketAsyncEventArgs.ReceiveMessageFromPacketInfo.Address为空
but SocketAsyncEventArgs.ReceiveMessageFromPacketInfo.Address is null
(添加)ReceiveMessageFromAsync()问题是一个错误.
(Add) ReceiveMessageFromAsync() problem is a bug.
它在.NET Framework 4.0中已修复
It is fixed in the .NET framework 4.0
谢谢.
推荐答案
也许尝试使用 ReceiveMessageFromPacketInfo .
Maybe try using Socket.ReceiveMessageFromAsync and then get the packet data using ReceiveMessageFromPacketInfo .
FYI 这是一种替代方法(请参见答案中的修改)
FYI this is an alternative way to do it (see the Edit in the answer)
HTH
这篇关于这是ReceiveFromAsync()错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!