Ответ 1
Да:
#include <sys/ioctl.h>
...
int count;
ioctl(fd, FIONREAD, &count);
У меня есть сервер, который получает непрерывный поток данных. В отличие от чтения нескольких раз из сокета, я хотел бы прочитать все данные в буфере приема сокета с одним системным вызовом read()
.
Конечно, я могу передать большой буфер, а read()
попытается заполнить его всеми доступными данными. Но это потеряло бы большую часть памяти, поскольку в большинстве случаев буфер malloc'ed был бы больше, чем фактические данные, доступные в сокете. Есть ли способ запросить доступные данные в сокете?
Да:
#include <sys/ioctl.h>
...
int count;
ioctl(fd, FIONREAD, &count);
Нет, нет. Даже если бы был способ сделать это, любой ответ, который вы получите, будет немедленно устаревшим (поскольку новые данные могут появиться в любое время).
Обратите внимание, что когда вы передаете буфер в read()
, функция вернется, когда будет считываться сколько-нибудь количество данных (хотя бы один байт), вместо того, чтобы ждать полного заполнения буфера.
Вам нужно попробовать отправить и получить команду, а также сможете читать и писать в символе сокета по символу, чтобы не потерять память и даже лучшую связь.
Вы можете использовать Non-bloking sockets или выбрать()/poll() для этого. Я предпочитаю неблокирующие сокеты, потому что я могу делать другие вещи, ожидая новых данных.
Это "вид" ответа: recv(char* buffer, size_t nytes, int flags)
, где флаги OR'ed:
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 p >