[英]Non Blocking recv() in C Sockets
我在套接字中使用一個無限循環,如果它接收到一些數據,它應該接收它,或者如果它想發送它發送的數據,則在其中。 如下所示。 我正在使用select。 我只有一個插槽SD。
fd_set readsd;
int maxsd = readsd +1;
// all those actions of setting maxsd to the maximum fd +1 and FDSETing the FDs.
while(1)
{
FD_ZERO(&read_sd);
FD_SET(sd, &read_sd);
if(FD_ISSET(sd, &readsd))
{
//recv call
}
else
{
//send call
}
}
據我所知,select選擇一個套接字描述符之一,數據首先到達該套接字描述符。 但是這里我只有一個套接字,如果有數據我想接收,否則我想發送。
在這種情況下,上面給出的代碼可以嗎? 還是我不知道的其他選擇?
在那種情況下,上面給出的代碼是否還可以?
我沒有看到任何要選擇的電話。 另外,如果將“ maxsd”設計為select的第一個參數,則其值是錯誤的:它必須是最大的文件描述符+1。 無論如何,您可以僅使用標志MSG_DONTWAIT調用recv,在這種情況下,如果沒有要讀取的數據,它將返回錯誤。
這取決於……首先,您實際上在實際代碼中確實有一個select
調用嗎?
現在有關阻塞的問題...如果select
返回時套接字已設置為讀集,那么可以保證可以調用recv
而不會阻塞。 但是不能保證可用的數據量。 如果使用UDP,則將至少有一個(希望是完整的)數據包,但如果使用TCP,則可能只會得到一個字節。 對於某些具有消息邊界的協議,您可能不會收到完整的消息,因此必須循環調用recv
才能獲取所有消息,但不幸的是,這遲早會導致recv
調用阻塞。
簡而言之,使用select
幫助,但並非在所有情況下都有用。 真正保證recv
調用不會阻塞的唯一方法是使套接字變為非阻塞狀態。
我不太確定自己要做什么,因此我可以考慮以下兩種選擇:
將套接字設置為非阻塞
由於似乎您只有一個套接字,因此可以使用fcntl
將套接字設置為非阻塞模式,然后調用recv()
fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK);
// if fcntl returns no error, sock is now non-blocking
設置選擇計時器
使用select
可以設置一個計時器,即使沒有收到任何數據,也可以在一段時間后強制返回。
首先,我在您的代碼中找不到任何select
。
但是,您可以首先調用fcntl(fd, F_SETFL, flags | O_NONBLOCK)
以使套接字無阻塞。 然后,當您無法從recv
讀取任何內容時,檢查errno == EWOULDBLOCK
。 在這種情況下,您無需使用select
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.