Nenad Birešev
Nenad Birešev

Reputation: 377

TCPClient Buffer size exception

I am using simple TCP client app to send request to server. This is client code that sends client message to server. The server sends a response, but sometimes the response is an empty string.

I catched a breakpoint when it happened and saw that when i put mouse over client.ReceiveBufferSize it shows exception ObjectDisposedException.

Here is the code:

private string SendClientMsg(string textToSend, string handID)
{ 
    TcpClient client = new TcpClient(serverIP, port);
    NetworkStream nwStream = client.GetStream();
    //---create a TCPClient object at the IP and port no.---
    byte[] bytesToSend = ASCIIEncoding.ASCII.GetBytes(textToSend);

    //---send the text---
    nwStream.Write(bytesToSend, 0, bytesToSend.Length);

    //---read back the text---
    byte[] bytesToRead = new byte[client.ReceiveBufferSize];
    int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);
    string response = Encoding.ASCII.GetString(bytesToRead, 0, bytesRead);
    client.Close();
    return response;
    }
 }

This method belongs to a class. Multiple threads are using this method to send requests to server. Could it be that one thread opens the connection and starts sending but at the same time another thread closes the connection using client.Close()

I am not sure if all threads are sharing the same TcpClient object. (Is it a singleton object so it is shared by all threads?). If so I would have to put lock to make sure multiple threads are not accessing this method at the same time.

Upvotes: 0

Views: 664

Answers (1)

TimothyP
TimothyP

Reputation: 21755

Every time this method is called a new instance of TcpClient is created:

TcpClient client = new TcpClient(serverIP, port);

Only the calling thread has access to this instance, so that is not the issue.

The problem is that you are assuming that you will receive the entire
response in a single read:

int bytesRead = nwStream.Read(bytesToRead, 0, client.ReceiveBufferSize);

From MSDN:

The total number of bytes read into the buffer. This can be less than the number of bytes requested if that many bytes are not currently available, or zero (0) if the end of the stream has been reached.

It takes time for the server to respond and it takes time for the response
to be sent across the network. When you call Read the entire response may or may not be available yet, so you need to read in a loop until the end of the stream is reached.

var responseBuffer = new byte[client.ReceiveBufferSize];
var bytesRead = 0;
int read;
do
{
   read = nwStream.Read(responseBuffer, 0, client.ReceiveBufferSize);
} while (read > 0)

This is assuming the server closing the connection properly after handling the request.
If the connection remains open you will have to restort to a different method
to determine you have received the entire response to the request.

Upvotes: 1

Related Questions