Как я могу сказать, полон ли буфер сокета?

Категорические части на этом предмете были записаны Joe Celko, и он работал много их в книгу, названную Деревьями Joe Celko и Иерархиями в SQL для Присяжных острословов.

Он одобряет технику, названную ориентированными графами. Введение в его работу над этим предметом может быть найдено здесь

13
задан Crazy Chenz 26 November 2009 в 15:24
поделиться

5 ответов

You can try ioctl. FIONREAD tells you how many bytes are immediately readable. If this is the same as the buffer size (which you might be able to retrieve and/or set with another icotl call), then the buffer is full. Likewise, if you can write as many bytes as the size of the output buffer, then the output buffer is empty.

I don't how widely supported FIONREAD, FIONWRITE, and SIOCGIFBUFS (or equivalents) are. I'm not sure I've ever used any of them, although I've a sneaky feeling I've used similar functionality on Symbian for some reason or other.

Whether the call needs kernel mode to compute this is platform-specific. Vaguely trying to avoid system calls is not a valid optimisation technique.

A basic BSD-style sockets interface doesn't say anything much about read and write buffers. When does it matter whether the send buffer is empty? It certainly doesn't mean that all the data has been received at the other endpoint of the socket - it could be sitting in some router somewhere. Likewise, "your" read buffer being full doesn't guarantee that a write at the other end will block.

Generally speaking, you just read/write as much as you can and let the sockets layer handle the complexity. If you're seeing a lot of I/O completed with tiny sizes then maybe there's some performance problem. But remember that a stream socket will send/receive a packet at a time, containing a block of data. Unless TCP_NODELAY is set, it's not as though bytes are arriving by ones at the NIC, and you might end up making one read call per byte. They're arriving in packets, so most likely will become readable all at once, perhaps 1k-ish at a time. You're unlikely to be able to speed things up by holding off reading until there's a lot to read. In fact you might make it worse, because by the time your endpoint's read buffer is full, there's a risk that incoming data is being discarded because there's nowhere to store it, resulting in delays and re-sends.

11
ответ дан 1 December 2019 в 18:55
поделиться

Опрос файлового дескриптора с помощью select и нулевого тайм-аута - если select говорит, что он доступен для записи, буфер отправки не заполнен.

(О ... без системного вызова . Нет, не существует.)

Дополнение:

В ответ на обновленный вопрос вы можете использовать два ioctl на сокете TCP: SIOCINQ возвращает количество непрочитанных данных в буфере приема, а SIOCOUTQ возвращает количество неотправленных данных в очереди отправки. Я не верю, что для них существует какое-либо асинхронное уведомление о событиях, поэтому вам придется проводить опрос.

12
ответ дан 1 December 2019 в 18:55
поделиться

Принимая во внимание, что буфер ядра для сокетов находится в пространстве ядра, я сомневаюсь, что есть способ запросить размер без системного вызова.
С системными вызовами вы можете попробовать recv с PEEK.

ret = recv(fd, buf, len, MSG_PEEK);

Даст выполнить восстановление, но без очистки буфера.

3
ответ дан 1 December 2019 в 18:55
поделиться

Это невозможно без системного вызова. Но в чем проблема с системными вызовами?

2
ответ дан 1 December 2019 в 18:55
поделиться

Я думаю, что есть фундаментальная причина, по которой ваш подход ошибочен / обречен. Система не хочет сообщать вам, когда буфер чтения заполнен / буфер записи пуст, потому что эти события указывают на разрыв контракта между вами и системой. Если что-то доходит до этого (особенно в направлении чтения), то для вас будет слишком поздно для обеспечения бесперебойной работы стека протоколов. Еще несколько данных могут появиться, когда вы наконец решите прочитать буфер. Вы должны прочитать буфер до того, как он заполнится , в этом весь смысл буферизованного ввода-вывода.

0
ответ дан 1 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: