Reputation: 1913
this is my first question and I'm not English native speaker so sorry for my (maybe) inaccurate English.
I'm implementing real-time network engine and using Socket.xxxAsync() method.
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 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);
}
( first 14 bytes are message prefix,CRC and sequence number)
And two(or more) clients send UDP packet to server. ( sending rate is hundreds per second )
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:59368 2
192.168.0.1:59368 2
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 11111111111111111111111111111 <- wrong part
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:59368 2
192.168.0.1:50113 11111111111111111111111111111
192.168.0.1:59368 2
192.168.0.1:59368 2
I doubt packet error, but there was no error in packet(I confirmed with Wireshark)
Is this a bug ?
(Add)
I tried
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));
and replaced ReceiveFromAsync() with ReceiveMessageFromAsync().
but SocketAsyncEventArgs.ReceiveMessageFromPacketInfo.Address is null
(Add) ReceiveMessageFromAsync() problem is a bug.
It is fixed in the .NET framework 4.0
thank you.
Upvotes: 3
Views: 3445
Reputation: 5940
Maybe try using Socket.ReceiveMessageFromAsync and then get the packet data using ReceiveMessageFromPacketInfo .
FYI this is an alternative way to do it (see the Edit in the answer)
HTH
Upvotes: 1