请原谅我选择的措辞和/或术语混淆,在套接字编程方面我是个假人。我正在尝试连接到TCP服务器,编写消息并处理响应。我使用以下代码:
Dim tcpClient As Sockets.TcpClient = New TcpClient()
tcpClient.Connect(hostname, 9080)
Dim networkStream As NetworkStream = tcpClient.GetStream()
If networkStream.CanWrite And networkStream.CanRead Then
Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(body)
networkStream.Write(sendBytes, 0, sendBytes.Length)
Dim bytes(tcpClient.ReceiveBufferSize) As Byte
networkStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
Dim returndata As String = Encoding.ASCII.GetString(bytes)
End If
我可以看到服务器日志,并注意到当我停止调试时服务器只从套接字中读取。然后它处理消息并发送响应(这有点晚了我的客户端不再听了)
似乎需要首先关闭networkStream对象。但是,如果我这样做,我无法处理任何后续响应。我是否需要向已完成写入的服务器“发信号”?我是否需要完全使用其他型号?
答案 0 :(得分:1)
关闭/处置NetworkStream
不是必需的,但我会质疑数据的发送方式。你写过服务器了吗?我希望发送(和接收)数据的长度前缀或终止字符或短语。如果您只是编写这样的数据,服务器就无法知道它应该读取多少数据。
接收代码也是如此。您只是尝试阅读ReceiveBufferSize
,而不是使用服务器发送给您的长度。
您确定您使用的协议不包含这些元素吗?
另外,请记住Read
和大多数/所有其他Stream
个对象一样,保证您将获得所请求的字节数。它将读取最多该字节数,函数的返回值表示读取了多少。您通常必须设置循环结构以获取特定数字。有点像...
int bytesToRead = 1024; // sample
int totalBytesRead = 0;
int bytesRead = 0
while(bytesToRead > 0)
{
bytesRead = stream.Read(buffer, totalBytesRead, bytesToRead);
if(bytesRead == 0) throw new Exception("Connection closed");
totalBytesRead += bytesRead;
bytesToRead -= bytesRead;
}
这比典型的实现更冗长,让您了解需要发生的事情。更典型的是:
int bytesToRead = 1024;
int bytesRead = 0;
while((bytesRead += stream.Read(buffer, bytesRead, bytesToRead - bytesRead) <= bytesToRead - bytesRead) { }