none
udp 使用 SocketAsyncEventArgs,一段时间后可能出现收不到任何包或者发不出去任何包 RRS feed

  • 问题

  • hi

    我在使用SocketAsyncEventArgs做udp server的时候发现在一些服务器上会出现,一段时间可能收不到任何包或者发不出去任何包,主要代码如下


    SocketAsyncEventArgs receiveSocketArgs;


                m_maxConnectionNumber = maxConnectionNumber;
                m_SendArgPool = new SocketAsyncEventArgsPool(maxConnectionNumber);


                    //生成一定数量的对象池
                    for (int i = 0; i < m_maxConnectionNumber; i++)
                    {
                        SocketAsyncEventArgs sendsocketArgs = new SocketAsyncEventArgs();
                        sendsocketArgs.Completed += new EventHandler<SocketAsyncEventArgs>(sendSocketArgs_Completed);

                        m_SendArgPool.Push(sendsocketArgs);
                    }


                    listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                    listenSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
                    listenSocket.DontFragment = true;
                    listenSocket.EnableBroadcast = true;
                    listenSocket.Ttl = m_ttl;
                    listenSocket.SendTimeout = m_sendTimeOut;

                    listenSocket.Bind(bindAddr);

                        receivebuffer = new byte[ReceiveBufferSize];
                        receiveSocketArgs = new SocketAsyncEventArgs();
                        receiveSocketArgs.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                        receiveSocketArgs.Completed += new EventHandler<SocketAsyncEventArgs>(this.receiveSocketArgs_Completed);
                        receiveSocketArgs.SetBuffer(receivebuffer, 0, receivebuffer.Length);
                   

     

    public bool Start()
            {
                    StartAsyncReceive();

                return (true);

            }

    private void StartAsyncReceive()
            {
                    if (!listenSocket.ReceiveFromAsync(receiveSocketArgs))
                    {
                        processReceived(receiveSocketArgs);
                    }

            }

            /// <summary>
            /// 异步接收完成
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void receiveSocketArgs_Completed(object sender, SocketAsyncEventArgs e)
            {
                switch (e.LastOperation)
                {
                    case SocketAsyncOperation.ReceiveFrom:
                        this.processReceived(e);
                        break;
                    default:
                        throw new ArgumentException("The last operation completed on the socket was not a receive");
                }

            }

     void processReceived(SocketAsyncEventArgs e)
            {

                IPEndPoint remoteEP = (IPEndPoint)e.RemoteEndPoint;

                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                {
                   //do some thing

                }

                // 发出下一个接收动作
                StartAsyncReceive();

            }


     
            public bool SendAsync(byte[] data, int dataSize, EndPoint remoteEP)
            {


                try
                {
                    //每次发送前都取一个新的SocketAsyncEventArgs对象。
                    SocketAsyncEventArgs m_SendArgs = m_SendArgPool.Pop();
                    m_SendArgs.RemoteEndPoint = remoteEP;

                    m_SendArgs.SetBuffer(data, 0, dataSize);

                    if (!listenSocket.SendToAsync(m_SendArgs))
                    {
                        ProcessSent(m_SendArgs);
                    }
                    return true;
                }
                catch (System.Exception ex)
                {
                    return false;
                }



            }


            private void sendSocketArgs_Completed(object sender, SocketAsyncEventArgs e)
            {
                switch (e.LastOperation)
                {
                    case SocketAsyncOperation.SendTo:
                        this.ProcessSent(e);
                        break;
                    default:
                        throw new ArgumentException("The last operation completed on the socket was not a send");
                }
            }

            /// <summary>
            /// 异步发送完成
            /// </summary>
            /// <param name="e"></param>
            private void ProcessSent(SocketAsyncEventArgs e)
            {
                if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
                {

                   //do some thing
                }
                m_SendArgPool.Push(e);
            }




    2014年12月17日 12:30

全部回复

  • 你好:

    建议你对代码添加日志信息,检查在出错情况下是否有异常抛出。另外就是在出现错误的时候检查一下接收或者发送消息的端口是否可用(通过netstat命令或者一些端口查看工具)。

    另外就是建议你直接使用.Net已经封装好的UdpClient类来进行通讯,而不是通过Socket本身,.Net中封装好的类可以减轻很多通讯上数据处理的负担,更好的专注于业务逻辑。

    http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient(v=vs.110).aspx

    http://msdn.microsoft.com/en-us/library/tst0kwb1(v=vs.110).aspx


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2014年12月18日 5:38
    版主
  • 实际代码中是有日志的

    当接受不到数据的时候 就是ReceiveFromAsync后没有任何反应了,没有任何异常数据

    当发不出去数据的时候,报 AddressFamilyNotSupported

    2014年12月18日 6:41