TCPClient缓冲区大小异常

时间:2018-04-25 23:24:28

标签: c# buffer tcpclient

我使用简单的TCP客户端应用程序向服务器发送请求。 这是将客户端消息发送到服务器的客户端代码。 服务器发送响应,但有时响应是空字符串。

当它发生时我抓住了一个断点,并且发现当我将鼠标放在client.ReceiveBufferSize上时它显示异常ObjectDisposedException

以下是代码:

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;
    }
 }

此方法属于一个类。 多个线程正在使用此方法向服务器发送请求。 可能是一个线程打开连接并开始发送 但同时另一个线程使用client.Close()

关闭连接

我不确定所有线程是否共享相同的TcpClient对象。 (它是一个单例对象,所以它被所有线程共享?)。 如果是这样,我将不得不放置锁以确保多个线程不同时访问此方法。

1 个答案:

答案 0 :(得分:1)

每次调用此方法时,都会创建TcpClient的新实例:

TcpClient client = new TcpClient(serverIP, port);

只有调用线程才能访问此实例,因此这不是问题。

问题是你假设你会收到整个 单次阅读回复:

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

来自MSDN

  

读入缓冲区的总字节数。如果当前没有多个字节可用,则这可能小于请求的字节数,如果已到达流的末尾,则可以小于零(0)。

服务器响应需要时间,响应需要时间 通过网络发送。当您致电Read整个回复时 可能有也可能没有,所以你需要循环阅读,直到 到达流的末端。

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

这假设服务器在处理请求后正确关闭连接 如果连接保持打开状态,则必须重新使用其他方法 确定您收到了对请求的完整回复。