异步套接字接收的数据顺序错误或丢失

本文关键字:错误 顺序 数据 套接字 异步 | 更新日期: 2023-09-27 18:17:19

我以前问过这个话题,并认为我已经掌握了它,但我发现我在这里错过了一些东西。我在linux中有一些C代码,我通过套接字发送数据到我的c# winforms可视化代码。我用最快的速度从C发送数据,这是相当快的。但是在c#中,我的datagridview没有正确更新。如果我放慢向c#代码发送数据的速度,它就可以了。但我真的做不到。我真的要死了。

在c#中是这样的:

{
   . . .
sListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sListener.Bind(new IPEndPoint(0, 1994));
Listen();
}
private void Listen()
    {
        sListener.Listen(10);
        // Begins an asynchronous operation to accept an attempt 
        AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
        sListener.BeginAccept(aCallback, sListener);
    }
    public void AcceptCallback(IAsyncResult ar)
    {
        Socket listener = null;
        // A new Socket to handle remote host communication 
        Socket handler = null;
        try
        {
            // Receiving byte array 
            byte[] buffer = new byte[1024];
            // Get Listening Socket object 
            listener = (Socket)ar.AsyncState;
            // Create a new socket 
            handler = listener.EndAccept(ar);
            // Using the Nagle algorithm 
            handler.NoDelay = false;
            // Creates one object array for passing data 
            object[] obj = new object[2];
            obj[0] = buffer;
            obj[1] = handler;
            // Begins to asynchronously receive data 
            handler.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None,  new AsyncCallback(ReceiveCallback), obj);
            // Begins an asynchronous operation to accept an attempt 
            AsyncCallback aCallback = new AsyncCallback(AcceptCallback);
            listener.BeginAccept(aCallback, listener);
        }
        catch (Exception exc) { MessageBox.Show(exc.ToString()); }
    }
    public void ReceiveCallback(IAsyncResult ar)
    {
        try
        {
            // Fetch a user-defined object that contains information 
            object[] obj = new object[2];
            obj = (object[])ar.AsyncState;
            // Received byte array 
            byte[] buffer = (byte[])obj[0];
            // A Socket to handle remote host communication. 
            handler = (Socket)obj[1];
            // Received message 
            string content = string.Empty;
            // The number of bytes received. 
            int bytesRead = handler.EndReceive(ar);
            if (bytesRead > 0)
            {
                Array.Resize(ref buffer, bytesRead);
                double[] values = new double[buffer.Length / 8];
                int i = 0;
                values[i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                values[++i] = BitConverter.ToDouble(buffer, i * 8);
                this.Invoke((MethodInvoker)delegate()
                {
                    if (dataGridView1.Rows.Count > 5)
                    {
                        dataGridView1.Rows.RemoveAt(this.dataGridView1.Rows[5].Index);
                    }
                    dataGridView1.Rows[0].Cells[1].Value = values[0];
                    dataGridView1.Rows[1].Cells[1].Value = values[1];
                    dataGridView1.Rows[2].Cells[1].Value = values[2];
                    dataGridView1.Rows[3].Cells[1].Value = values[3];
                    dataGridView1.Rows[4].Cells[1].Value = values[4];
                });
            }
            // Continues to asynchronously receive data
            byte[] buffernew = new byte[1024];
            obj[0] = buffernew;
            obj[1] = handler;
            handler.BeginReceive(buffernew, 0, buffernew.Length,
            SocketFlags.None,
            new AsyncCallback(ReceiveCallback), obj);                   
        }
        catch (Exception exc) { MessageBox.Show(exc.ToString()); }
    }

异步套接字接收的数据顺序错误或丢失

你的异步代码正在触发异步,这是预期的…但这意味着处理的顺序可能与接收的顺序不同。例如:

.NET receive message 1
.NET receive message 2
.NET finish receive message 2
.NET finish receive message 1

这里你假设你会看到1,然后是2,因为这是它们被接收的顺序,但不是它们被接收的顺序。

如果你的数据的顺序很重要,你必须一次发送所有的数据在一个大的批处理(坏),或接收它顺序(底层TCP应该确保消息以适当的顺序传递)。