异步客户端套接字,无序接收缓冲区数据

时间:2014-04-17 15:29:25

标签: c# ios .net sockets asynchronous

所以我在这里有两件事。一个iPad应用程序与在Linux服务器上运行的python脚本交谈。 python脚本将大约〜1K字节的iPad应用程序数据文件发送到~10K字节。我偶尔会发生一个非常奇怪的事件(比如可能每100或200次尝试一次)。

I modeled my Asynchronous Client Socket from this example。在我在下面发布的ReceiveCallback函数中,我将数据接收到我的缓冲区中,如下所示:

string stuffWeReceived = Encoding.ASCII.GetString(state.buffer,0,bytesRead);

但我的问题是,有时我会收到无序的数据。我有时会强调这个词。在我的测试中,我有5台iPad并排运行我的应用程序,并且正在向所有5个ipad发送相同的确切数据。 99.9%的时间他们正确地按正确的顺序接收数据,但有一半的时间,iPad将无法接收数据。

I was told in this post, that Data should never come out of order... Any ideas as to what I'm doing wrong to trigger this?

以下是数据的控制台输出示例,其顺序正确无误:

enter image description here Link to above picture

enter image description here Link to above picture

我知道发送数据的服务器上的python脚本正在正确发送数据,因为正如我上面提到的,在我的测试中,我有5台运行应用程序的iPad,只有1台iPad会出现这个问题(这个问题只会发生)一小部分时间......)

我正在后台线程中查看我的异步客户端套接字,如下所示:

    AsyncClient_Thread = new Thread(() => AsyncClient.StartClient());
    AsyncClient_Thread.IsBackground = true;
    AsyncClient_Thread.Start();


    public void StartClient()
    {
        // Connect to a remote device.
        try {
            // Establish the remote endpoint for the socket.                

            string ipAddress = appDel.wallInteractionScreen.Host_WallServer;
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipAddress), port);

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

            // Connect to the remote endpoint.
            ClientSocket.BeginConnect( remoteEP, 
                new AsyncCallback(ConnectCallback), ClientSocket);
            connectDone.WaitOne();

            Receive(ClientSocket);
            receiveDone.WaitOne();
        } 
        catch (Exception e) {
            Console.WriteLine("Error in AsyncClient StartClient: ");
            Console.WriteLine(e.Message);
            Console.WriteLine(e.StackTrace);
        }

        //          Console.WriteLine("Finished StartClient");
    }

这是我的ReceiveCallback功能

    private static void ReceiveCallback( IAsyncResult ar )
    {
        AppDelegate appDel = (AppDelegate)UIApplication.SharedApplication.Delegate;

        // I added this InvokeOnMainThread to see if it would solve the "data out of order problem", but it didn't
        appDel.InvokeOnMainThread (delegate{
            Console.WriteLine("ReceiveCallback IsMainThread = " + NSThread.IsMain);

            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.
                    string stuffWeReceived = Encoding.ASCII.GetString(state.buffer,0,bytesRead);

                    string debugString = "~~ReceiveCallback~~ len = " + stuffWeReceived.Length + " bytesRead = " + bytesRead + ": " + stuffWeReceived;
                    if ( appDel.diagnosticsScreen.DebugAsyncReceiveBuffer_Switch.On )
                    {
                        appDel.diagnosticsScreen.AppendToDebugLog(debugString);
                    }
                    Console.WriteLine(debugString);


                    // Send this data to be received
                    appDel.wallInteractionScreen.ChitterChatter.ReceiveSomeData(stuffWeReceived);

                    // Get the rest of the data.
                    client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
                        new AsyncCallback(ReceiveCallback), state);
                } else {
                    // Signal that all bytes have been received.
                    receiveDone.Set();
                }
            } 
            catch (Exception e) {
                Console.WriteLine("Error in AsyncClient ReceiveCallback: ");
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        });

    }

1 个答案:

答案 0 :(得分:-1)

这最终成为我在C#端的代码中的线程/锁定问题。我从头开始重写了我的锁定机制,现在有100%的时间都能正常工作。感谢所有帮助我看到这一切的人!