【发布时间】:2024-01-09 22:50:01
【问题描述】:
我正在尝试实现一个单播 UDP 服务器,该服务器在多个客户端请求服务时为它们提供服务。正在发送的消息是一个更新的计数器值。我希望服务器能够在有请求时接收传入请求,并且在没有请求时,继续一个接一个地向客户端列表发送数据。我尝试使用select() 来实现它,但它总是返回 0。我做错了什么?
服务器端 - 实现select():
while(1)
{
// >>> Step #3 <<<
// Wait to receive a message from client
sleep(10); // Unix sleep for 1 second
printf(".\n");
printf("Waiting for recvfrom() to complete... \n");
FD_ZERO(&readhandle);
FD_SET(server_s1, &readhandle);
FD_SET(server_s2, &readhandle);
timeout_interval.tv_sec = 10;
timeout_interval.tv_usec = 500000;
int retval = select(max_servers+1, &readhandle, NULL, NULL, &timeout_interval);
if (retval == -1)
{
printf("Select error\n");
}
else if (retval == 0)
{
printf("timeout\n");
}
else
{
if (FD_ISSET(server_s1, &readhandle))
{
addr_len = sizeof(client_addr);
errno = 0;
retcode = recvfrom(server_s1, in_buf, sizeof(in_buf), 0, (struct sockaddr *)&client_addr, &addr_len);
if (retcode > 0)
{
// Copy the four-byte client IP address into an IP address structure
memcpy(&client_ip_addr, &client_addr.sin_addr.s_addr, 4);
// Print an informational message of IP address and port of the client
printf("IP address of client = %s port = %d) \n", inet_ntoa(client_ip_addr),ntohs(client_addr.sin_port));
// Output the received message
printf("Received from client: %s \n", in_buf);
client_port = ntohs(client_addr.sin_port);
insert_at_end(client_port, client_addr);
printf("Client added :\n");
display();
}
// >>> Step #4 <<<
// Send to the client using the server socket
sprintf(out_buf, "Sending update from SERVER to CLIENT %d",counter++);
struct node *tmp;
tmp=head;
while(tmp!=NULL)
{
retcode = sendto(server_s1, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&(tmp -> client_addr), sizeof(tmp -> client_addr));
printf("IP address of client = %s port = %d) \n", inet_ntoa(tmp -> client_addr.sin_addr),ntohs(tmp -> port_num));
if (retcode < 0)
{
printf("*** ERROR - sendto() failed \n");
exit(-1);
}
tmp=tmp->next;
}
}
if(FD_ISSET(server_s2, &readhandle))
{
addr_len = sizeof(client_addr);
errno = 0;
retcode = recvfrom(server_s2, in_buf, sizeof(in_buf), 0, (struct sockaddr *)&client_addr, &addr_len);
if (retcode > 0)
{
// Copy the four-byte client IP address into an IP address structure
memcpy(&client_ip_addr, &client_addr.sin_addr.s_addr, 4);
// Print an informational message of IP address and port of the client
printf("IP address of client = %s port = %d) \n", inet_ntoa(client_ip_addr),ntohs(client_addr.sin_port));
// Output the received message
printf("Received acknowledgement from the client: %s \n", in_buf);
client_port = ntohs(client_addr.sin_port);
retcode = sendto(server_s2, out_buf, (strlen(out_buf) + 1), 0,(struct sockaddr *)&(client_addr), sizeof(client_addr));
if (retcode < 0)
{
printf("*** ERROR - sendto() failed \n");
exit(-1);
}
}
}
}
}
【问题讨论】: