1

我正在使用 Berkeley C 套接字在 C/C++ 中编写一个实时网络系统,它在基于滴答的时间间隔上工作。每次滴答,客户端程序都会使用 recvfrom() 从套接字读取数据。

问题是如果服务器没有发送任何数据,客户端将读取在套接字上发送的最后一个数据。

例如客户端(伪代码)

while (true)
{
   if (time_to_update())
   {
      int n = recvfrom(data,...);
      printf("%s",data);
   }
}

和服务器:

int main()
{
   int m = recvfrom(data,...);
   int n = sendto(...,"hello");
}

然后客户端会继续打印“你好”,而我只需要它打印一次。

这与这个问题很相似,recvfrom re-reading data on socket ,但我不太明白答案,它似乎更普遍地解决了问题。

我猜数据存储在网卡上的缓冲区中,在这种情况下,在读取 1 次后是否可以清除缓冲区?我想到的另一种方法是对数据包进行编号并且只读取新的数据包,但是所有类型都是有限的,所以我希望可能有一种更清洁的方法。

我将如何做到这一点,以便客户端只读取一次接收到的数据?

4

2 回答 2

4
printf("%s",data);

常见问题。不测试错误;不测试流结束;不使用长度。应该:

if (n < 0)
{
    perror("recv");  // or better
    break;
}
else if (n == 0)
    break; // peer has disconnected 
else
    printf("%.*s", n, data);

如果您不检查这些事情,您将永远旋转并在它们发生时打印垃圾。

我猜数据存储在网卡上的缓冲区中

不。

在这种情况下,在 1 次读取后是否可以清除缓冲区

阅读它会清除它。你的问题在别处。

于 2016-05-31T12:32:27.190 回答
3

您是否正在检查变量中的返回值m?它很可能会返回零或 -1(因此没有读取任何字节),并且您会一遍又一遍地重新打印相同的值,data因为没有任何东西可以修改它。

于 2016-05-31T12:29:51.263 回答