目前我正在使用單個服務器,單個客戶端udp聊天應用程序。最初我使用了默認情況下的阻塞套接字。現在我想將套接字轉換爲非阻塞狀態,以便客戶端和服務器之間的通信可以在沒有障礙的情況下完成... 我已經在服務器端實現了選擇功能,但是它啓動客戶端獲取發送一次,其中顯示在服務器端的消息,隨後客戶端和服務器得到響應,所以現在我展示瞭如何有我實現在服務器端的select()函數:c中的非阻塞套接字
//Declaring a non-blocking structure
fd_set readfds,writefds;
// clear the set ahead of time
FD_ZERO(&readfds);
FD_ZERO(&writefds);
// add our descriptor to the set
FD_SET(sd, &readfds);
FD_SET(sd, &writefds);
/value of sd+1
int n=sd+1;
由於我想要接收和發送數據,我已經在循環中實現了選擇功能:
int client_length = (int)sizeof(struct sockaddr_in);
int rv = select(n, &readfds, NULL, NULL, NULL);
if(rv==-1)
{
printf("Error in Select!!!\n");
exit(0);
}
else if(rv==0)
{
printf("Timeout occurred\n");
}
else
if (FD_ISSET(sd, &readfds))
{
int bytes_received = recvfrom(sd, buffer,SIZE, 0, (struct sockaddr *)&client, &client_length);
if (bytes_received < 0)
{
fprintf(stderr, "Could not receive datagram.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
}
還用於發送數據:
fgets(buffer,SIZE,stdin);
int rv1 = select(n, &writefds, NULL, NULL, NULL);
if(rv1==-1)
{
printf("Error in Select!!!\n");
exit(0);
}
else if(rv1==0)
{
printf("Timeout occurred\n");
}
else
if(FD_ISSET(sd,&writefds))
{
if(sendto(sd, buffer,strlen(buffer), 0, (struct sockaddr *) &client,client_length)<0)
{
printf("Error sending the file! \n");
exit(1);
}
}
}
所以我會很感激,如果somoone讓我知道是否我做這個正確與否,如果是OK,然後會在客戶端相同implelementation解決我的問題?
記住'選擇()'覆蓋其輸入,所以你在每次調用該函數的時間來重新創建'fd_set's(或複製這些文件)。我不確定這是否是你的問題,但它是'select()'代碼的常見問題。 –
@ Jonathan Leffler:我應該在循環中初始化「readfds」和「writefds」嗎? –
是的 - 你需要在循環中初始化'readfds'和'writefds',因爲當你調用它時select()會修改它們。 –