[英]In a non blocking socket connect, select() always returns 1
我有這個代碼段,旨在使用套接字連接連接到服務器。 但是,如果它在一定時間內無法連接到服務器,我希望它停止嘗試。 我嘗試使用此非阻塞套接字和 select 命令執行此操作,但 select 始終返回 1,表示服務器存在,而我給它的地址不存在任何內容。 有任何想法嗎?
SOCKET tcp_client( char *hname, char *sname ) {
fd_set fdset;
struct sockaddr_in peer;
SOCKET s;
FD_ZERO(&fdset);
// FD_SET(STDIN, &fdset);
FD_SET(s, &fdset);
errno=1;
struct timeval tv;
tv.tv_sec = 15;
set_address( hname, sname, &peer, "tcp" );
s = socket( AF_INET, SOCK_STREAM, 0 );
int n = 1;
fcntl(s, F_SETFL, O_NONBLOCK);
if ( !isvalidsock( s ) )
{
printf("Socket Call Failed: %s\n", strerror(errno));
return(0);
}
int x = 0;
int status = connect( s, ( struct sockaddr * )&peer, sizeof( peer ) );
if(status < 0) {
printf("Status: %i\n", status);
}
int retVal = select(s+1, &fdset, NULL, NULL, &tv);
printf("retVal: %i\n", retVal);
if (retVal == 1) {
int so_error;
socklen_t slen = sizeof so_error;
getsockopt(s, SOL_SOCKET, SO_ERROR, &so_error, &slen);
if (so_error == 0) {
printf("work\n");
x =1;
} else {
printf("fail\n");
x = 0;
}
} else {
printf("noSocks\n");
}
if (x ==0 )
{
printf("Connect Failed: %s\n", strerror(errno));
L("libOnexc: Connect to socket failed");
close(s);
return(0);
}
return s;
}
您需要檢查套接字是否准備好寫入(選擇的第二個fd_set *
參數),而不是讀取(第一個)。
我看到的一個問題是您在創建套接字之前將 s 粘貼在 fdset 中。 你需要做
FD_SET(s, &fdset);
在您創建了套接字之后,因為 s 只是一個 integer,因此在調用 socket() 之前不會是正確的值。
編輯
像這樣:
.
.
.
SOCKET s;
errno=1;
struct timeval tv;
tv.tv_sec = 15;
set_address( hname, sname, &peer, "tcp" );
s = socket( AF_INET, SOCK_STREAM, 0 );
int n = 1;
fcntl(s, F_SETFL, O_NONBLOCK);
if ( !isvalidsock( s ) )
{
printf("Socket Call Failed: %s\n", strerror(errno));
return(0);
}
FD_ZERO(&fdset);
FD_SET(s, &fdset); // don't put socket in set until it is actually created
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.