2

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

4

3 回答 3

3

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

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

于 2012-09-11T11:03:09.200 回答
0

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

于 2012-09-16T10:06:47.233 回答
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调用是阻塞的,直到数据可供读取(除非您将套接字设置为解除阻塞)。

您可以循环接收所有响应。

于 2012-09-11T11:17:46.190 回答