firia2000
firia2000

Reputation: 1913

Is this ReceiveFromAsync() bug?

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

here

thank you.

Upvotes: 3

Views: 3445

Answers (1)

Hertzel Guinness
Hertzel Guinness

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

Related Questions