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