我使用C#编写了一个Client-Server应用程序。
客户端异步发送一条消息,其中包含一个定义消息大小的4字节标头,服务器等待整个消息(它知道大小),然后引发DataReceived
事件。当我异步发送和接收数据时,这一切都正常。
在某些时候,我想模拟一个错误的连接,其中有2个段使用Send()
而不是BeginSend()
一个接一个地发送
public void SendSyncString(string str, Commands cmd)
{
BinaryWriter bw = new BinaryWriter(new MemoryStream());
bw.Write((int)cmd);
bw.Write((int)str.Length);
bw.Write(Encoding.ASCII.GetBytes(str));
bw.Close();
byte[] data = ((MemoryStream)(bw.BaseStream)).ToArray();
bw.BaseStream.Dispose();
SendSync(data,1);
}
public void SendSync(byte[] data,int delay)
{
//create |dataLength|data| segment
byte[] dataWithHeader = Combine(BitConverter.GetBytes(data.Length), data);
//send first block of data, delay, and then send the rest
socket.Send(dataWithHeader, 0, 4, SocketFlags.None);
Thread.Sleep(delay*1000);
socket.Send(dataWithHeader, 5, dataWithHeader.Length - 5, SocketFlags.None);
}
不有效。我希望了解为什么。 如果我只是一个TCP字节流,并且无法知道每个段何时到达, 为什么我不能像我希望的那样将它分成段,并像上面一样发送它们(假设前4个字节是完全发送的)?
感谢您的见解。
答案 0 :(得分:4)
因为你的第一个socket.Send调用只发送了4个字节:
socket.Send(dataWithHeader, 0, 4, SocketFlags.None);
即,发送偏移量为0,1,2和3的字节(总共4个字节)。记住socket.Send的第三个参数是长度参数,而不是结束位置。
因此,这一行有一个错误:
socket.Send(dataWithHeader, 5, dataWithHeader.Length - 5, SocketFlags.None);
它从偏移量5,6,7 ..发送字节到数组的末尾。 跳过字节4。因此,接收器可能会阻塞,因为它只接收完整消息的一个字节。
应该是:
socket.Send(dataWithHeader, 4, dataWithHeader.Length - 4, SocketFlags.None);
你去。
答案 1 :(得分:1)
我想模拟一个错误的连接,其中2个段一个接一个地发送
这不是'糟糕的联系'。对于任何TCP连接来说,这都是完全合法的方式。如果接收软件没有正确处理,则表明它没有正确写入。
假设前4个字节已完全发送
你不能假设。