我使用简单的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对象。 (它是一个单例对象,所以它被所有线程共享?)。 如果是这样,我将不得不放置锁以确保多个线程不同时访问此方法。
答案 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)
这假设服务器在处理请求后正确关闭连接 如果连接保持打开状态,则必须重新使用其他方法 确定您收到了对请求的完整回复。