今天的遊戲開發client測試程式,非常多,因為出現client。後connect成功。代碼證recv系統調用。後來發現,可能是由于socket預設模式被阻止,這将使很多client
接處于連結卻不能資料傳輸狀态。
後來改動socket為非堵塞模式,但在connect的時候,發現傳回值為-1,剛開始以為是connect出現錯誤,但在server上看到了連結是ESTABLISED狀态。
證明連結是成功的
但為什麼會出現傳回值是-1呢? 經過查詢資料,以及看stevens的APUE,也發現有這麼一說。
當connect在非堵塞模式下,會出現傳回-1值。錯誤碼是EINPROGRESS,但怎樣推斷connect是聯通的呢?stevens書中說明要在connect後,繼續推斷該socket是否可寫?
若可寫,則證明連結成功。怎樣推斷可寫,有2種方案,一種是select推斷是否可寫,二用poll模型。
select:
int CheckConnect(int iSocket)
{
fd_set rset;
FD_ZERO(&rset);
FD_SET(iSocket, &rset);
timeval tm;
tm. tv_sec = 0;
tm.tv_usec = 0;
if ( select(iSocket + 1, NULL, &rset, NULL, &tval) <= 0)
close(iSocket);
return -1;
}
if (FD_ISSET(iSocket, &rset))
int err = -1;
socklen_t len = sizeof(int);
if ( getsockopt(iSocket, SOL_SOCKET, SO_ERROR ,&err, &len) < 0 )
printf("errno:%d %s\n", errno, strerror(errno));
return -2;
if (err)
errno = err;
return -3;
return 0;
poll:
int CheckConnect(int iSocket) {
struct pollfd fd;
int ret = 0;
socklen_t len = 0;
fd.fd = iSocket;
fd.events = POLLOUT;
while ( poll (&fd, 1, -1) == -1 ) {
if( errno != EINTR ){
perror("poll");
return -1;
}
}
len = sizeof(ret);
if ( getsockopt (iSocket, SOL_SOCKET, SO_ERROR, &ret, &len) == -1 ) {
perror("getsockopt");
return -1;
}
if(ret != 0) {
fprintf (stderr, "socket %d connect failed: %s\n",
iSocket, strerror (ret));
return -1;
}
return 0;
}