目前我正在使用单个服务器,单个客户端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()会修改它们。 –