2013-05-21 50 views
0

我在我的应用程序中使用winsock来维护客户端 - 服务器连接,并使用非阻塞套接字来完成此操作。但有时,当我收到FD_READ消息时,看起来recv()不是返回一个,而是两个数据包。FD_READ:recv()立即返回两个数据包

我试图改变数据包的大小,使它们彼此不同,然后将它与数据量recv()正在返回进行比较。我100%确定我会不时收到两个数据包。我认为我的ping功能是被责备的。我的应用程序中有一个线程时常发送ping消息。然后另一方回复另一条消息。不知道这是否是最好的方式,但无论如何,现在并不重要。

我所知道的确有时候这些消息会“混合”,因此recv()一次返回“ping请求”和“ping应答”。它是如何发生的? recv()应该只返回单个呼叫发送的数据量吗?即使有时客户端或服务器获得“ping请求”消息并作出回复,但在发送其自己的“ping请求”消息时,即使这种不幸的时间可能,也不应该使另一方能够将一个数据包与另一个数据包相区别并返回每FD_READ消息一个?

回答

1

TCP是数据流,而不是数据包流。 UDP是一个数据包流。正如安东尼所说,如果你使用TCP,你必须处理一部分数据结束和下一部分开始的地方。

+0

所以如果我使用UDP,我不会得到这个问题? – PookyFan

+0

好吧,我明白了。还有一件事:当我从recv()得到这个双包数据包时,我是否会收到一个或两个FD_READ消息?我的意思是 - 当我得到FD_READ并调用recv()将两个数据包都收到缓冲区时,我的应用程序是否会发送另一个FD_READ消息? – PookyFan

+0

划伤我先前的评论。使用UDP会比较容易,因为正如标记中所提到的,它确实符合数据包边界(一次读取会生成一个数据包)。这对你来说可能更容易使用,但你仍然需要一种方法来区分数据包(大小可能不总是工作)。 – Anthony

1

在上一次调用recv和获取两个数据包的时间之间确实收到了两个数据包。 recv不会一次获得一个数据包,它会读取缓冲区中可用的所有数据。这意味着可能有多个可用的数据消息,或者可能只有部分消息可用。 (如果消息足够大,它将被拆分成多个数据包。)解码自己的数据是您的工作。一个简单的方法是通过添加一个包含一些信息的标题来帮助您,如消息标识或预期数据大小的指示。一般来说,使用CRC来验证数据完整性(并确保您有完整的消息)的脚注也不会造成任何影响。