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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14047802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:07:57  来源:igfitidea点击:

How to check amount of data available for a socket in C and Linux

clinuxsockets

提问by Jimm

I have a server that receives a continuous stream of data. As opposed to reading multiple times from a socket, I would like to read the entire data in socket receive buffer with one system call to read().

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

Of course I can pass a large buffer and read()will try to fill it with all available data. But this would waste a lot of memory as most of the times the malloc'ed buffer would be bigger than actual data available on socket. Is there a way to query the available data on a socket?

当然,我可以传递一个大缓冲区,read()并尝试用所有可用数据填充它。但这会浪费大量内存,因为在大多数情况下,malloc 的缓冲区会大于套接字上可用的实际数据。有没有办法查询套接字上的可用数据?

采纳答案by fizzer

Yes:

是的:

#include <sys/ioctl.h>

...

int count;
ioctl(fd, FIONREAD, &count);

回答by Greg Hewgill

No, there is not. Even if there were a way to do this, any answer you get would be immediately out of date (because new data may arrive at any time).

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

Note that when you pass a buffer to read(), the function will return when there is anyamount of data to read (at least one byte), instead of waiting for the buffer to completely fill.

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

回答by yeyo

You could use Non-bloking sockets, or select()/poll() for that matter. I prefer non-blocking sockets because I can do other things while waiting for new data.

您可以使用Non-bloking sockets或 select()/poll() 。我更喜欢非阻塞套接字,因为我可以在等待新数据的同时做其他事情。

回答by jim mcnamara

This is a "sort of" answer: recv(char* buffer, size_t nytes, int flags)where flags is OR'ed with:

这是一种“某种”答案: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.

Such that you can see if an arbitrary number of bytes exists in the buffer, without irreversibly reading the buffer. This is a half-answer because it is not the most efficient way to do this, and MSG_PEEK is usually employed when messages have known length headers maybe like this:

这样您就可以查看缓冲区中是否存在任意数量的字节,而不会不可逆地读取缓冲区。这是一个半答案,因为它不是执行此操作的最有效方法,并且当消息具有已知长度的标头时通常使用 MSG_PEEK 可能是这样的:

000123DT001    

where 00123is the length of the whole message including header, DTis the type of message, and 001is the number of retries by the sender. The idea is that you can fetch something that tells you how many bytes make a complete read of a message. You are not interested in messages. But that is the reason behind MSG_PEEK

其中00123是包括标题在内的整个消息的长度, 是消息DT的类型,001是发件人的重试次数。这个想法是你可以获取一些东西,告诉你有多少字节可以完整读取消息。您对消息不感兴趣。但这就是背后的原因MSG_PEEK

回答by akp

i think you are trying to get many packets with single system call to reduce the overhead due to system calls.

我认为您正在尝试通过单个系统调用获取许多数据包,以减少由于系统调用引起的开销。

so u can try PACKET sockets interfaces for linux 2.4 or 2.6+ kernelstry this http://lxr.free-electrons.com/source/Documentation/networking/packet_mmap.txt

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

回答by ravi bhuva

You have to try send and receive command as well as you are able to read and write in socket character by character so no wastage of memory and even better communication.

您必须尝试发送和接收命令,并且您可以逐个字符地在套接字中读写,因此不会浪费内存,甚至可以更好地进行通信。