qq_40557951 2021-06-08 14:15 采纳率: 50%
浏览 234
已结题

SOCKET异步通信,服务端对多个客户端,接收数据时异常.求大佬瞄一眼给个建议

异常信息:读取消息出错:System.ArgumentException: 未从此类上对应的异步方法中返回 IAsyncResult 对象。
参数名: asyncResult
   在 System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult, SocketError& errorCode)
   在 System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult)

 

代码示例:

public Socket handler; 

 public void MainForm_Load(object sender, EventArgs e)
        {
            try
            {
                // 允许不安全线程调用
                Form.CheckForIllegalCrossThreadCalls = false;
                serverIp = ConfigurationSettings.AppSettings["serverIp"].ToString();
                localIp = ConfigurationSettings.AppSettings["localIp"].ToString();
                Logging.Info("程序启动...." + localIp);
                // 开启监听服务 必须在一个新的线程里面. 不然界面会block
                Logging.Info("开始监听服务:" + serverIp.ToString() + ": " + localTcpPort.ToString());
                th = new Thread(StartTcpServer);
                th.Start();
            }
            catch (Exception ex)
            {
                Logging.Error("初始化窗体失败:" + ex.ToString());
            }
        }

 // 开启TCP 监听
        public void StartTcpServer()
        {
            // Establish the local endpoint for the socket.  
            // The DNS name of the computer  
            // running the listener is "host.contoso.com".  
            IPAddress ipAddress = IPAddress.Parse(localIp);
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, localTcpPort);

            // Create a TCP/IP socket.  
            Socket listener = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming connections.  
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
                while (true)
                {
                    // Set the event to nonsignaled state.  
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.  
                    updateStatusLabel("等待数据...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);
                    // Wait until a connection is made before continuing.  
                    allDone.WaitOne();
                }
            }
            catch (Exception e)
            {
                // 理论上一定不会出现异常. 要是出现的话.停止程序 手动重启程序.
                Logging.Error(string.Format("启动TCP监听错误:{0}", e.ToString()));
                this.Close();
            }
        }

      // 链接创建成功
        public void AcceptCallback(IAsyncResult ar)
        {

            // Signal the main thread to continue.  
            allDone.Set();
            // Get the socket that handles the client request.  
            Socket listener = (Socket)ar.AsyncState;
            handler = listener.EndAccept(ar);

            // Create the state object.  
            StateObject state = new StateObject();
            state.workSocket = handler;
            //handler.Blocking
            //int str = listener.ReceiveTimeout;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
            //WaitOne

            // this.Invoke((MethodInvoker)delegate ()
            this.Invoke((MethodInvoker)delegate ()
            {
                this.lblStatus.Text = "连接成功!";
                Logging.Info("TCP连接成功");
            });

        }

 

 public void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            // Retrieve the state object and the handler socket  
            // from the asynchronous state object.  
            StateObject state = (StateObject)ar.AsyncState;
            handler = state.workSocket;
            try
            {
                // Read data from the client socket.
                int bytesRead = 0;
                if (handler != null && handler.Connected)
                {
                    bytesRead = handler.EndReceive(ar);
                }
                Logging.Info("收到数据长度:" + bytesRead);
                Logging.Info("收到数据跟新时间, 上次收到数据时间:" + lastActiveTime.ToString());
                lastActiveTime = DateTime.Now;
                if (bytesRead > 0)
                {
                   //消息处理


                }
                else
                {
                    // 这里不用设置回调
                    this.Invoke((MethodInvoker)delegate ()
                    {
                        this.lblStatus.Text = "连接断开!";
                    });
                    // 这里理论上不用设置回调. 不大可能就发个空的东西 过来. 安全起见还是 让他设置回调. 第二次设置的时候 
                    // 回出错 从而终止这个链接.
                    //handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    //  new AsyncCallback(ReadCallback), state);
                    handler.Close();
                    Logging.Error("收到0字节链接可能某个断开!");
                }
            }
            catch (Exception e)
            {
                this.Invoke((MethodInvoker)delegate ()
                {
                    this.lblStatus.Text = "连接断开!";
                });
                Logging.Error("读取消息出错:" + e.ToString());
            }
            //finally
            //{
            //    try
            //    {

            //    }
            //    catch (Exception e)
            //    {
            //        // 客户端异常断开,监听应该还在。 只是这个连接坏掉了。
            //        Logging.Error(string.Format("读取数据出错2:{0}", e.ToString()));
            //        //Thread.Sleep(3000);
            //        //StartTcpServer();
            //    }
            //}
        }

 

开始不会异常,偶尔跑一段时间后就会报:“读取消息出错:System.ArgumentException: 未从此类上对应的异步方法中返回 IAsyncResult 对象。
参数名: asyncResult”这个异常,定位在 bytesRead = handler.EndReceive(ar);,有大佬可以告诉我是为什么吗?求知道的大佬解答一下

  • 写回答

3条回答 默认 最新

  • 有问必答小助手 2021-06-09 19:29
    关注

    你好,我是有问必答小助手。为了技术专家团更好地为您解答问题,烦请您补充下(1)问题背景详情,(2)您想解决的具体问题,(3)问题相关代码图片或者报错信息。便于技术专家团更好地理解问题,并给出解决方案。

    您可以点击问题下方的【编辑】,进行补充修改问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 6月16日

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!