Socket tcp c# how to clear input buffer?

2019-02-28 22:45发布

问题:

I'm writing an application for windows phone and I need to communicate with a server and transmit data. The SERVER is written in C++ and I cannot modify it. The CLIENT is what I have to write. The Server is designed such that the client connect to it and transmit data. The connection remains open for all the transmission. By writing my code in C# I am able to receive data from the server but after the first receive, the data that I read in the buffer are alway the same. So I need a way to flush the input buffer so I can receive the new data (data are sent continuously). I'm using the class defined in here:

http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202858%28v=vs.105%29.aspx

thanks a lot !!

I used this code for Receiving in the SocketClient.cs :

public string Receive()
    {
        string response = "Operation Timeout";

        // We are receiving over an established socket connection
        if (_socket != null)
        {
            // Create SocketAsyncEventArgs context object
            SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;

            // Setup the buffer to receive the data
            socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);

            // Inline event handler for the Completed event.
            // Note: This even handler was implemented inline in order to make 
            // this method self-contained.
            socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
            {
                if (e.SocketError == SocketError.Success)
                {
                    // *********************************************
                    // THIS part of the code was added to receive 
                    // a vector of 3 double
                    Double[] OdomD = new Double[3];
                    for (int i = 0; i < 3; i++)
                    {
                        OdomD[i] = BitConverter.ToDouble(e.Buffer, 8 * i);
                    }
                    // *********************************************

                }
                else
                {
                    response = e.SocketError.ToString();
                }

                _clientDone.Set();
            });

            // Sets the state of the event to nonsignaled, causing threads to block
            _clientDone.Reset();

            // Make an asynchronous Receive request over the socket
            _socket.ReceiveAsync(socketEventArg);

            // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
            // If no response comes back within this time then proceed
            _clientDone.WaitOne(TIMEOUT_MILLISECONDS);
        }
        else
        {
            response = "Socket is not initialized";
        }

        return response;
    }

The Connect() method is exactly the same reported in the link above. So when the application start, the Connect() method is called as follow:

SocketClient client = new SocketClient();
// Attempt to connect to server for receiving data
            Log(String.Format("Connecting to server '{0}' over port {1} (data) ...", txtRemoteHost.Text, 4444), true);
            result = client.Connect(txtRemoteHost.Text, 4444);
            Log(result, false);

That is done just once at the beginning, then I need receive this array of 3 double that is updated every second. So I use:

Log("Requesting Receive ...", true);
            result = client.Receive();
            Log(result, false);

The problem is that also if I debug the code and stop the execution inside Receive(), I always read the same value, that is the first value sent by the server. What I'm expecting is that every time I call client.Receive(), I get the new value, but this is not appening.

I had a similar problem by writing the same client in Matlab environment. I solved the problem by using the function flushinput(t) before to read the input buffer. In this way I was able to read always the last data sent by the server. I'm lookin for a function similar to that one ..

The size of the input buffer is fixed equal to the data that I'm expecting to receive, in that case is 24 bytes ( 3* sizeof(double) ) ..

Thanks a lot for you time !!

回答1:

oleksii is right, you should call client.Receive() in a loop. You can choose to start a thread that covers the receive section of your code. Also note that client.Receive() will keep trying to receive from the buffer, and it will get stuck if there is no data available.



回答2:

The main question was **how to clear the input buffer? ** or am I wrong?=!

Nevertheless; since you don't have a fixed buffer denoted as seen from you posted code and receive it via the SocketAsyncEventArgs, you could clear it with:

Array.Clear(e.Buffer, 0, e.Buffer.Length);