如果我知道此客户端已连接到服务器,如何仅从所需的客户端接收消息?
recvfrom(sockfd, buf, BUFFSIZE, MSG_PEEK,
(struct sockaddr *)&addr, &caddrlen);
addr将被相应的数据替换,但我只想从一个客户端接收数据
答案 0 :(得分:2)
recvfrom(sockfd, buf, BUFFSIZE, MSG_PEEK,
(struct sockaddr *)&addr, &caddrlen);
if(addr.sin_addr.s_addr == "ADDRESS_OF_DESIRED_CLIENT")
{
//ALLOW USER
}
对于IPV4,“ addr.sin_addr.s_addr”是一个整数,但是您也可以从字符串中获取地址。
答案 1 :(得分:2)
如果我知道此客户端已连接到服务器,如何仅从所需的客户端接收消息?
除非真正不使用AF_INET
或AF_INET6
系列中的数据报套接字,否则不能这样做,除非不希望的客户端在较低的级别被阻止,例如通过防火墙。至少,如果您希望在来自不希望的客户端的邮件到达后能够继续从所需的客户端接收邮件,则不是这样。网络驱动程序为您排队数据报,并且您需要按顺序处理它们,其中“处理”数据报的C API将通过为此目的的多个系统调用之一来接收数据报,例如recvfrom()
您可以在收到消息后 进行区分,例如通过丢弃不需要的客户端中的消息。但是,正如MSG_PEEK
的{{1}}标志所提供的那样,它在不使消息出队的情况下用于检索消息数据的用途非常有限。特别是,这不符合您指定的目的-您仍然需要通过不使用recvfrom()
的后续调用来接收每条消息。相反,我建议您仅通过MSG_PEEK
读取数据,检查地址以确定它是否来自您感兴趣的客户,并进行适当处理。
如果要同时处理多个客户端,则有一些替代方法。一个相对简单的功能是拥有一个可能在专用线程中运行的功能,该功能可以接收所有传入的消息并根据其源地址适当地分派它们。另一种选择是为每个客户端打开一个新的(数据报)套接字,每个套接字都在其自己的端口上,并设置一个协议,通过该协议,您可以告诉每个客户端在首次联系后要使用哪个端口。来自这些其他端口上的意外客户端的数据报将是错误的,因此可以安全地拒绝。
当然,后者是面向连接协议的近似值。如果它对您似乎有吸引力,那么也许您应该看一下流套接字而不是数据报套接字。这样不仅可以让您毫不费力地实现客户专用性,还可以提供可靠且有保证的按顺序通信。