有UDP套接字时如何使用select函数

时间:2012-09-11 10:54:24

标签: c select udp multicast

我想创建一个多客户端 - 一个服务器测验应用程序。在此,首先,客户端将连接到服务器并将自己注册。然后,服务器将向每个已将自己注册到服务器的客户端多播一个问题。然后,客户端将回答答案,答案将仅发送给服务器。然后服务器将每个客户的分数发送给相应的客户端 这就是我在上述申请中要做的事情 1.因为我也multicast,这就是为什么我将我的服务器套接字设为SOCK_DGRAM(即UDP)。然后我使用CLASS-D ip地址来创建一个组(服务器将组播到哪个组)。然后使用setsockopt,我将客户端添加到该组,以便他们可以接收问题 2.我想倾听所有客户的答案,所以我在考虑使用select。它使用套接字描述符在各种客户端之间进行选择,以了解哪些客户端已准备好进行读取 但问题是,当我使用SOCK_DGRAM套接字时,它不会执行listenaccept功能。所以,我不会得到一个套接字描述符(由accept返回)。这就是为什么,我将无法使用select(因为它只使用文件描述符) 那么,我该如何继续,因为我想使用UDP功能 - MULTICASTING,以及TCP功能 - 每个连接的套接字描述符。

3 个答案:

答案 0 :(得分:3)

即使使用UDP和未连接的套接字,您仍然可以使用select之类的功能。只需将服务器套接字绑定到一个地址,然后将该套接字用于select。当套接字可读时,客户端发送了一些内容,例如sendto你可以做,例如recvfrom

但是,我真的建议你使用TCP套接字,它会使许多事情变得更简单,特别是当谈到通信协议时(记住UDP包可能会丢失或乱序,你必须自己处理) )。

答案 1 :(得分: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次调用阻塞,直到数据可供读取(除非您将套接字设置为取消阻止)。

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

答案 2 :(得分:0)

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