0
我想通過說將我的問題完全解決,方法是通過將Select()的超時選項設置爲NULL來解決問題。Winsock - 選擇在偵聽套接字上的超時導致每個後續的Select呼叫失敗
但我想使用超時,所以這是我的問題。服務器程序非常簡單,它監聽連接,接受它們並打印到控制檯。
的問題是,在選擇第一超時後,選擇將返回-1(MSDN小到無的文件給我,什麼會導致-1從選擇(返回),只知道它的錯誤信號),並有效地阻止來自程序的更多通信。
服務器 - main.cpp中
int main(){
/* variables */
int iResult, iSendResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
bool exit=false;
int foundRoom, tempFoundRoom;
fd_set readfds, writefds;
struct timeval tv;
long double counter=0;
int maxfd=0;
/* Server variables */
WSADATA wsaData;
SOCKET ListenSocket = INVALID_SOCKET;
SOCKET ClientSocket = INVALID_SOCKET;
struct addrinfo *result = NULL;
struct addrinfo hints;
printf("~SERVER~\n");
/* Initialize Winsock*/
initialize_winsock(wsaData, hints, &result);
/* Set socket and bind to TCP listening socket */
set_socketandbind(ListenSocket, result, maxfd);
//non-blocking mode
u_long iMode=1;
ioctlsocket(ListenSocket,FIONBIO,&iMode);
ioctlsocket(ClientSocket,FIONBIO,&iMode);
// clear the set ahead of time
FD_ZERO(&readfds);
//FD_ZERO(&writefds);
//add our descriptors to the set
FD_SET(ListenSocket, &readfds);
//wait until either socket has data ready to be recv()d (timeout 5 secs)
tv.tv_sec = 5;
tv.tv_usec = 0;
/* main loop */
for(;;){
cout << "Maxfd: " << ListenSocket << " \ " << maxfd << endl;
//select
int rv = select(ListenSocket+1, &readfds, NULL, NULL, &tv);
cout << "Updateing... rv: " << rv << endl;
if (rv == -1) {
perror("Select: "); // error occurred in select()
}else if (rv == 0){
printf("Timeout occurred! No data after 5 seconds.\n");
}else{
// one or both of the descriptors have data
if (FD_ISSET(ListenSocket, &readfds)) {
// Accept a client socket
ClientSocket=accept(ListenSocket, NULL, NULL);
cout << "Connected a user." << endl;
}
counter++;
}
cout << endl;
Sleep(500);
};
/* Unset server socket */
closesocket(ListenSocket);
system("pause");
return 0;
}
輸出應該是超時,超時,超時,因爲多數民衆贊成應該如何選擇()的工作,以及它是如何工作的我的客戶端上。相反,輸出是超時,錯誤,錯誤,錯誤:
你的意思是每次select()被調用時,都會重置電視結構? –
這實際上並不能解決問題。我需要添加FD_ZERO和FD_SET並在循環中重置電視,不僅在每個循環中添加電視。爲什麼是這樣? –
因爲select()更改FD結構。如果你有超時時間,沒有準備好,所以相應的位被清除了,所以你需要重置它。 – EJP