我在c#中使用套接字时遇到问题.这是一个例子.假设我发送数字1,然后我立即发送数字2.我遇到的问题有时是应该接收它的客户端将收到包含'12'的数据包.我想知道是否有内置的方法来区分数据包而不使用字符或东西来分离数据.
再说一遍,我说了两个包.一个数字为'1',一个数字为'2'.服务器接收数据为"12"的1个数据包.我不想将数据包与字符分开,例如':1 :: 2:'或类似的东西,因为我并不总是能控制传入数据的格式.
有任何想法吗?
就像我这样做
client.Send(new byte[1]{'1'}, 1,SocketFlags.None);
client.Send(new byte[1]{'2'}, 1,SocketFlags.None);
Run Code Online (Sandbox Code Playgroud)
然后在服务器端
byte[] data = new byte[1024];
client.Receive(data);
Run Code Online (Sandbox Code Playgroud)
即使我做两个单独的发送,数据有时会以"12"返回.
TCP是一种流媒体协议,因此您将始终接收自上次读取以来已到达的任何数据,直至接收方端的流媒体窗口大小.该缓冲区可以填充从发送方发送的任何给定大小的多个分组接收的数据.
虽然在示例中您已经在接收端观察到1个包含2个字节的统一blob数据,但是可以接收1个字节乘1个字节的序列(由发送方发送),具体取决于网络条件以及许多可能的组合如果您正在执行非阻塞读取,则读取0,1和2字节.在典型的非拥塞LAN或环回设置上进行调试时,如果发送端没有延迟,您几乎不会看到这一点.在网络堆栈的较低级别,有一些方法可以检测每个数据包的传输,但它们不会用于典型的TCP编程,并且不在应用范围内.
如果您切换到UDP,那么每个数据包都会在发送时收到,这符合您的期望.这可能更适合您,但请记住,UDP没有传送承诺,网络路由可能导致数据包无序传送.
您应该考虑分隔数据或找到其他方法来检测何时到达应用程序定义的数据单元的末尾,并坚持使用TCP.
TCP/IP工作在一个流抽象,没有一个数据包的抽象.
当你打电话时Send
,你没有发送数据包.您只是将字节附加到流.
通话时Receive
,您没有收到数据包.您只从流中接收字节.
因此,您必须定义"消息"的开始和结束位置.只有三种可能的解决方案:
Receive
数据,直到获得那么多字节.Receive
长度前缀直到它到达,解码它以获得消息的实际长度,然后保持Receive
消息本身.你必须自己做消息框架.TCP/IP无法为您完成.