我在uni项目中遇到了一些麻烦。我从C ++客户端向C#服务器发送tcp消息,服务器分两部分接收它。有可能阻止它下来吗?我输出正在客户端发送的数据,所有数据都在1件中,所以不能这样。这是我的OnReceiveData方法:
void OnReceiveData(IAsyncResult result){
try{
int readbytes = myStream.EndRead(result);
if (readbytes <= 0){
//client is not connected to the server anymore
CloseSocket();
return;
byte[] newBytes = new byte[readbytes];
Buffer.BlockCopy(readBuff, 0, newBytes, 0, readbytes);
myStream.BeginRead(readBuff, 0, readbytes, OnReceiveData,
null);
string output =
System.Text.Encoding.ASCII.GetString(newBytes, 0,
readbytes);
Text.WriteLog(output);
ServerHandleData.HandleData(connectionID, newBytes);
}
catch (Exception e)
{
Text.WriteError("Error Code: " + e);
CloseSocket();
}
}
谢谢!
答案 0 :(得分:1)
没有办法“阻止它”,这就是流 TCP的工作方式。
简而言之,由于TCP正在流式传输,因此没有消息边界。只是连续的字节流。
要在数据之间实现某种消息传递或边界,那么您需要提出自己的应用程序层协议以放在TCP之上。例如,您可以引入某种消息边界令牌,特殊字符,字节或字符/字节序列,这表示当前消息已结束。或者,您可以发送固定大小的消息头,其中包括实际消息数据的大小。
然后,在接收时,您需要循环接收,直到您检测到消息结尾。为此,最简单的方法是使用具有数据长度的固定大小的标头,因为您只需尝试读取(标头或数据的)长度,减少接收每次迭代的字节数,直到没有更多内容为止接收(接收的字节数达到零)。
答案 1 :(得分:1)
不,TCP是流,而不是单个“大块”数据。
如the EndRead example中所见,一条消息可能被分成多个部分,因此您必须阅读这些部分并将其连接起来。
readbytes = myStream.EndRead(result);
myCompleteMessage = String.Concat(myCompleteMessage,
Encoding.ASCII.GetString(myReadBuffer, 0,
readbytes));
// message received may be larger than buffer size so loop through until you have it all.
while(myStream.DataAvailable) {
myStream.BeginRead(myReadBuffer, 0, myReadBuffer.Length,
new AsyncCallback(NetworkStream_ASync_Send_Receive.myReadCallBack),
myStream);
}
答案 2 :(得分:0)
所以一段时间后,我设法修复了它。问题是开始读取中的读取字节被设置为先前的消息长度,这迫使它拆分消息。我是通过手动设置尺寸来解决的。
感谢您的建议! :)