То, что я прошу, кажется невозможным. В итоге я вызвал recv () с флагом MSG_PEEK
. Это заставит последующие вызовы recv () или recvmsg () в библиотеке читать те же данные.
Без каких-либо других вызовов я могу использовать его для удобного просмотра только одного байта. Давайте предположим, что мне нужно посмотреть вперед 2 байта. Я бы позвонил recv(fd, buf, 2, MSG_PEEK)
. Если 1 из 2 байтов уже прибыл, то recv немедленно вернется, независимо от того, сколько раз я его называю. Я могу использовать epoll_ctl с EPOLLIN | EPOLLET
для ожидания второго байта. Если я хочу узнать, был ли EOF впоследствии, мне нужно EOPLLIN | EPOLLET | EPOLLRDHUP
. (Обратите внимание, что EPOLLHUP
не будет возвращено в EOF.) Поэтому, используя epoll_ctl
, я могу избежать вызова recv в занятом цикле опроса для чтения 2-го байта.
Я только что проверил в своей системе Linux, что по умолчанию я могу посмотреть примерно 900 КБ в сокет. (SO_RECVBUF
для меня составляет 1 МБ по умолчанию, уменьшение его с помощью setsockopt , кажется, уменьшает, сколько можно получить, но не на постоянную сумму. Может быть, я уменьшу это слишком поздно?)
Даже комбинация MSG_PEEK
и EPOLLET
- это обходной путь, потому что они все еще не позволяют мне читать непроизвольные байты в сокете. Все, что они позволяют мне, - это смотреть уже прибывшие байты, не потребляя их.