我正在使用C# Socket类(带有异步方法和SocketAsyncEventArgs类)实现一个客户机服务器应用程序。我必须同时实现TCP和UDP功能。
我的用法是从服务器到客户端以数据包的形式发送一些命令,反之亦然,对重要命令使用TCP,对非重要命令使用UDP。
据说,Nagle算法可能会导致合并多个发送到一个接收的TCP数据包,所以我为TCP套接字设置了NoDelay (尽管我从未体验过它!)
另一个问题可能是IP碎片,但我认为在接收之前会在某个地方组装碎片。因此,它必须是安全的发送高达64 at发送和接收一次!
我的问题是::我可以假设每个接收的都对应于100%情况下的one发送吗?(我知道一次发送可能会导致UDP丢失的数据包零接收)
我问这个问题的理由是:1) circumstances是实现拆分合并的数据包,还是2)在接收中实现合并的分组,还是有一些可以安全地假定每一个接收到的都对应于一个发送?
P.S: --我使用Socket.ReceiveAsync作为TCP,Socket.ReceiveFromAsync用于UDP数据包。
发布于 2020-08-21 09:34:14
不,对于TCP来说,您根本不能依赖这一点。一个Send可能需要多个Receive调用才能读取,而对Receive的单个调用可能会接收到多个Send,因此您无法(就连接上的设置而言)来阻止这一点,因此您必须能够在应用程序中处理它。
如果要在TCP流上交换可变长度消息,通常确定整个消息是否已被读取的方法是实现某种形式的“帧化”,即在每条消息的前缀加上指定以下消息大小的固定字节数(例如,用于编码Int32的4个字节)。
在接收端,您首先读取前4个字节前缀(请记住,您可能需要使用多个Receive!),将其转换为一个Int32,然后该Int32告诉您还需要读取多少字节,以确保您已经从流中读取了一个消息。要读取下一条消息,只需重复该过程。
https://stackoverflow.com/questions/63520056
复制相似问题