如何在C和Linux中检查可用的套接字数据量

我有一台服务器接收连续的数据stream。 与从套接字多次读取相反,我想通过一个系统调用read()read()套接字接收缓冲区中的全部数据。

当然,我可以通过一个大的缓冲区, read()会尝试填充所有可用的数据。 但是这会浪费大量的内存,因为大部分malloc缓冲区的大小都比socket上的实际数据大。 有没有办法查询套接字上的可用数据?

是:

 #include <sys/ioctl.h> ... int count; ioctl(fd, FIONREAD, &count); 

不,那里没有。 即使有办法做到这一点,任何答案你会立即过时(因为新的数据可能随时到达)。

请注意,当您将一个缓冲区传递给read() ,函数将在有任何数量的数据要读取时(至少一个字节)返回,而不是等待缓冲区完全填充。

你必须尝试发送和接收命令以及你可以逐字读写套接字,所以没有浪费的内存,甚至更好的沟通。

你可以使用Non-bloking套接字 ,或者为此选择()/ poll()。 我更喜欢非阻塞套接字,因为我可以在等待新数据时做其他事情。

这是一个“排序”的答案: recv(char* buffer, size_t nytes, int flags)其中标志是OR:

 MSG_PEEK This flag causes the receive operation to return data from the beginning of the receive queue without removing that data from the queue. Thus, a subsequent receive call will return the same data. 

这样就可以看到缓冲区中是否存在任意数量的字节,而不会不可逆地读取缓冲区。 这是一个半答案,因为它不是最有效的方法,MSG_PEEK通常在消息已知长度标题可能是这样的时候使用:

 000123DT001 

其中00123是包含头部的整个消息的长度, DT是消息的类型,并且001是发送者重试的次数。 这个想法是,你可以获取一些东西,告诉你有多少个字节可以完整地读取一条消息。 你对消息不感兴趣。 但这就是MSG_PEEK背后的原因

我认为你正在试图通过单一的系统调用来获取很多数据包,以减少系统调用的开销。

所以你可以尝试PACKET套接字的Linux 2.4或2.6以上的内核尝试这个http://lxr.free-electrons.com/source/Documentation/networking/packet_mmap.txt