[英]Unread (unget) to a BSD socket?
我的C程序已從Linux上的TCP套接字讀取(使用read(2)或recv(2) )幾個字節。 是否有可能將這些字節推回,以便后續的read(2)和recv(2)調用(在我無法控制的庫內深度發出)將再次讀取它們?
flag of recv(2) , and I'm going to use it as a workaround if pushing back turns out to be impossible. 我知道recv(2)的標志,如果推回原來是不可能的話,我將把它用作解決方法。
最好的選擇是更改工作流程,這樣您就不需要讀取然后再推回數據。 看起來兩次似乎很丑陋(我同意這可能是合法的)。
但是如果這不可能或非常困難,你可以使用LD_PRELOAD
( dlsym
)劫持read
和recv
系統調用。
我所要求的似乎是不可能的。 我最后用標志MSG_PEEK
調用recv()。 這將使庫中的后續recv()或recvmsg()調用讀取相同的數據。
沒有任何其他調用,我可以使用它來方便地向前看只有一個字節。 我們假設我需要向前看2個字節。 我打電話給recv(fd, buf, 2, MSG_PEEK)
。 如果2個字節中的1個已經到達,那么無論我多少次調用它,recv都會立即返回。 我可以將epoll_ctl與EPOLLIN | EPOLLET
EPOLLIN | EPOLLET
等待第二個字節。 如果我想知道之后是否有EOF,我需要EOPLLIN | EPOLLET | EPOLLRDHUP
EOPLLIN | EPOLLET | EPOLLRDHUP
EOPLLIN | EPOLLET | EPOLLRDHUP
。 (請注意, EPOLLHUP
不會在EOF上返回。)因此,通過使用epoll_ctl
我可以避免在繁忙的輪詢循環中調用recv來讀取第二個字節。
我剛剛在我的Linux系統上驗證過,默認情況下我可以通過這種方式查看大約900 kB的套接字。 (默認情況下, SO_RECVBUF
為1 MB,使用setsockopt減少它似乎會減少可以接收的數量,但不會減少一致數量。也許我減少它太晚了?)
即使MSG_PEEK
和EPOLLET
的組合也是一種解決方法,因為它們仍然不允許我將任意字節EPOLLET
到套接字。 他們讓我做的只是偷看已經到達的字節而不消耗它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.