2009-11-24 43 views
0

请原谅我选择措辞和/或术语混淆,在套接字编程方面,我是一个虚拟角色。我正在尝试连接到TCP服务器,写入消息并处理响应。我使用下面的代码: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对象需要先关闭。但是,如果我这样做,我不能处理任何后续的响应。我是否需要向已完成写作的服务器发送信号?我需要完全使用不同的模型吗?

+1

你是否也编写了TCP服务器?如果是这样,你可以发布处理传入连接的代码吗? – ristonj 2009-11-24 14:30:20

+0

好点(因此upvote :))。我无权访问TCP服务器源。 – 2009-11-24 14:37:24

回答

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) { } 
相关问题