简体   繁体   English

异步套接字客户端ReceiveCallback未执行

[英]Ansychronous Socket Client ReceiveCallback not executing

Hi am am working on a C# Winforms Application using the sample code below: 嗨,我正在使用下面的示例代码来开发C#Winforms应用程序:

https://msdn.microsoft.com/en-us/library/bbx2eya8(v=vs.110).aspx https://msdn.microsoft.com/zh-CN/library/bbx2eya8(v=vs.110).aspx

It connects to the right IP address and port number but after sending a string command and waiting for a response the application gets stuck because the ReceiveCallback is not being executed therefore not setting the receiveDone ManualResetEvent. 它连接到正确的IP地址和端口号,但是在发送字符串命令并等待响应之后,由于未执行ReceiveCallback,因此应用程序卡住了,因此未设置receiveDone ManualResetEvent。 I am 100% sure im suppose to receive back a response but instead the application just gets stuck and does not execute the ReceiveCallback method. 我100%肯定应该接收回响应,但是应用程序只是卡住了,并且不执行ReceiveCallback方法。 What could possibly be the reason why ReceiveCallback method is not being executed? 为何未执行ReceiveCallback方法的原因可能是什么?

private static void Receive(Socket client)
    {
        try
        {
            // Create the state object.
            StateObject state = new StateObject();
            state.workSocket = client;

            // Begin receiving the data from the remote device.
            client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

 private static void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Retrieve the state object and the client socket 
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));

                // Get the rest of the data.
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1)
                {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

Context: The application is an interface for a DC electric Torque Tool controller. 上下文:该应用程序是直流电动扭矩工具控制器的接口。 I connect to the controllers Ip address and port 4545 than i am able to send Open Protocol commands to change settings. 我连接到控制器的IP地址和端口4545,而不是能够发送“开放协议”命令来更改设置。

Solution found at https://social.msdn.microsoft.com/Forums/vstudio/en-US/05dcda20-06f9-419b-bfc0-bcb8cfeb3693/socket-receivecallback-not-sending-notification-when-buffer-has-emptied?forum=csharpgeneral 可在https://social.msdn.microsoft.com/Forums/vstudio/en-US/05dcda20-06f9-419b-bfc0-bcb8cfeb3693/socket-receivecallback-not-sending-notification-when-buffer-has-emptied找到的解决方案?forum = csharpgeneral

Here is my fixing code. 这是我的固定代码。 Check the "Add to fix" part please. 请检查“添加至修复”部分。

try
        {
            // Retrieve the state object and the client socket   
            // from the asynchronous state object.  
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;
            // Read data from the remote device.  
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0)
            {
                // There might be more data, so store the data received so far.  
                state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
            }                                                       // Add to fix
                                                                    // Add to fix
            int bytesRemain = state.workSocket.Available;           // Add to fix
            if (bytesRemain>0)                                      // Add to fix
            {                                                       // Add to fix
                //  Get the rest of the data.  
                client.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None,
                    new AsyncCallback(ReceiveCallback), state);
            }
            else
            {
                // All the data has arrived; put it in response.  

                if (state.sb.Length >= 1)                 //<-- Fixed from>1 to >=1
                    response = state.sb.ToString();
                else
                    response = ""; //OR null;

                // Signal that all bytes have been received.  
                receiveDone.Set();
            }
        }

Here is my analysis to why the orignal can't work: 以下是我对原始广告无法正常工作的分析:

  • I send a msg to the server like "*IDN?". 我将味精发送到服务器,例如“ * IDN?”。 The server replied a message of 34 letters like "Instrument ABC,xx,xx,xx". 服务器回复了34个字母的消息,例如“ Instrument ABC,xx,xx,xx”。 It has been read successfully by the ReceiveCallBack. ReceiveCallBack已成功读取它。 so the bytesRead = 34. 所以bytesRead = 34。
  • But there is a check say if bytesRead >0, might be ,just might be there is still data there, so the ReceiveCallBack itself launched a new client.BeginReceive again. 但是有一个检查说,如果bytesRead> 0,可能是,可能只是那里仍然有数据,所以ReceiveCallBack本身启动了一个新客户端。BeginReceive再次。
  • But this time, there is no data from the server. 但是这次,服务器没有数据。 so the client wait and wait and wait, the ReceiveCallBack never been called back again ... 因此客户端等待并等待,等待,再也不会再次调用ReceiveCallBack ...
  • So the else-branch of the ReceiveCallBack is never executed. 因此,永远不会执行ReceiveCallBack的else分支。 Thus the 'response' variable never set and receiveDone never been Set either. 因此,“ response”变量从未设置过,receiveDone也从未设置过。

I would add this as a comment, but I don't have the reputation. 我将其添加为评论,但我没有声誉。

  1. Where are you calling this from? 你从哪儿打来的? You should have a loop which is calling Receive once you've connected to your socket. 连接到套接字后,应该有一个调用Receive的循环。 Could you show us the code where Receive is being called? 您能告诉我们调用Receive的代码吗?

  2. What is the value of StateObject.BufferSize? StateObject.BufferSize的值是什么?

  3. Are any exceptions being thrown? 是否有任何异常抛出?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM