当你有UDP套接字时如何使用select功能

问题描述 投票:0回答:3

我想制作一个多客户端-单服务器测验应用程序。在此,首先,客户端将连接到服务器并注册自己。然后,服务器将向每个已向服务器注册的客户端多播一个问题。然后,客户端将给出答案,该答案将仅发送到服务器。然后服务器会将每个客户端的分数发送给各自的客户端。
这就是我在上面的应用程序中尝试做的事情-
1. 因为我也有

multicast
,这就是为什么我将我的服务器套接字设置为
SOCK_DGRAM
(即UDP)。然后我使用
CLASS-D
IP 地址来创建一个组(服务器将向哪个组进行多播)。然后是使用
setsockopt
,我将客户添加到这个组中,以便他们可以收到问题。
2.因为我想听听所有客户的答案,所以我想到使用
select
。它使用套接字描述符在各个客户端之间进行选择,以了解哪个客户端已准备好读取。
但问题是,当我使用 SOCK_DGRAM 套接字时,它不执行
listen
accept
功能。因此,我不会获得套接字描述符(由
accept
返回)。这就是为什么,我将无法使用
select
(因为它仅使用文件描述符)。
那么,我该如何继续,因为我想使用 UDP 功能 - 多播,以及 TCP 功能 - 每个连接的套接字描述符。

c udp multicast posix-select
3个回答
3
投票

即使使用 UDP 和未连接的套接字,您仍然可以使用

select
等功能。只需将服务器套接字绑定到一个地址,然后使用该套接字即可
select
。当套接字可读时,客户端已发送一些内容,例如
sendto
你可以这样做
recvfrom

但是,我真的建议您使用 TCP 套接字,它会让很多事情变得更简单,尤其是在通信协议方面(请记住,UDP 包可能会丢失或出现故障,您必须自己处理)。


0
投票

正如您所说,

select
在这里没有用,因为服务器端只有一个套接字。 该套接字用于发送带有
sendto

的数据报
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

dest_addr
中指定数据报的目标地址。

在 UDP 套接字上使用

recvfrom(2)
类似:

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

src_addr
是发送者地址,因此您可以识别发送响应的客户端。

recvfrom
调用会阻塞,直到数据可供读取为止(除非您将套接字设置为解除阻塞)。

您可以循环接收所有回复。


0
投票

你走在正确的轨道上,但你不需要listen()或accept()。只需选择可读性即可。当套接字变得可读时,读取它。你可能根本不需要 select() ,实际上,只是一个阻塞读取,如果你愿意的话可以超时。

© www.soinside.com 2019 - 2024. All rights reserved.