簡體   English   中英

非阻塞套接字選擇在連接后返回1

[英]non blocking socket select returns 1 after connect

首先,我想說的是這是另一個問題: 相似但不相同

我的代碼如下所示:

struct addrinfo hints, *res;
struct sockaddr* serveraddr;

memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

int res2 = getaddrinfo(ip, port, &hints, &res);
printf("getaddrinfo() res: %d, %d\n", res2, errno);

serveraddr = res->ai_addr;

//create new socket

int soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
printf("socket() res: %d, %d\n", socket, errno);

//set nonblocking mode
unsigned long on = 1;
res2 = ioctl(soc, FIONBIO, &on);
printf("ioctl() res: %d\n, %d", res2, errno);

res2 = connect(soc, serveraddr, sizeof(struct sockaddr));
printf("connect() res: %d, %d\n", res2, errno);

//check if socket is ready
fd_set wfds;
FD_ZERO(&wfds);
FD_SET(soc, &wfds);

struct timeval t;
t.tv_sec=15;
t.tv_usec=0;

res2 = select(soc + 1, 0, &wfds, 0, &t);
printf("select() res: %d, %d\n", res2, errno);`

我正在連接到存在的計算機(IP地址存在,但是沒有服務器在我嘗試連接的端口上偵聽)。

選擇始終返回1。為什么? 根據man的說法,它應該超時並返回0。此后,當我嘗試向套接字寫入內容時,它返回-1 / ECONNREFUSED。

這是預期的行為嗎? 如果是,連接select()后如何檢查?

我不知道手冊頁中的哪個位置應該超時。

如果沒有防火牆丟棄數據包,則連接將很快被拒絕(來自主機的一個數據包,一個數據包回復)。 因此,一旦收到重置,連接插座上的“事件”就會出現。 這將喚醒select ,至少具有一個活動套接字。

首次讀取或寫入該套接字的嘗試將返回潛在的連接錯誤。

這是正確的行為 ,因為掛起的錯誤會導致套接字變得可讀可寫。 與其他任何系統調用一樣,您需要顯式檢查錯誤情況。 您可以將套接字包含在fdset異常(select()的第四個參數)中,然后直接接收通知,或者以后可以通過多種方式檢查錯誤。

小心寫套接字,因為可能會發生SIGPIPE。 通常,您應該設置SIGPIPE處理程序,並與EPIPE同步處理錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM