Unix: 从 ( )

Unix: recvfrom( )

如果我知道此客户端已连接到我的服务器,如何仅从所需客户端接收消息?

recvfrom(sockfd, buf, BUFFSIZE, MSG_PEEK,
                (struct sockaddr *)&addr, &caddrlen);

addr会被相应的数据替换,但我只想从一个客户端接收数据

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" 是一个 int,但您也可以从字符串中获取地址。

How to receive message from only desired client if I know that this client has been connected to my server?

您不能使用 AF_INETAF_INET6 系列中的数据报套接字真正做到这一点,除非不需要的客户端在较低级别被阻止,例如通过防火墙。至少,如果您希望能够在来自不需要的客户端的消息到达后继续接收来自所需客户端的消息,则不会。网络驱动程序为您排队数据报,您需要按顺序处理它们,其中 C API for "handling" 数据报是通过服务于该目的的几个系统调用之一接收它,例如作为 recvfrom().

您可以在收到 消息后对其进行区分,例如丢弃来自不需要的客户端的消息。但是,正如 recvfrom()MSG_PEEK 标志所提供的那样,它具有有限的特殊用途来检索消息数据而不将其出队。特别是,这不符合您声明的目的——您仍然需要通过不使用 MSG_PEEK 的后续调用来接收每条消息。相反,我建议简单地通过 recvfrom() 读取数据,检查地址以确定它是否来自您感兴趣的客户端,并适当地处理它。

如果您想同时处理多个客户端,那么您有一些选择。一个相对简单的方法是在专用线程中有一个函数,也许 运行,它接收所有传入的消息并根据它们的源地址适当地分派它们。另一种方法是为每个客户端打开一个新的(数据报)套接字,每个客户端都在自己的端口上,并设置一个协议,您可以通过该协议告诉每个客户端在第一次联系后使用哪个端口。来自这些额外端口上的意外客户端的数据报将是错误的,因此可以安全地拒绝。

当然,后者是面向连接协议的近似值。如果它对您很有吸引力,那么也许您应该查看流套接字而不是数据报套接字。这不仅可以让您轻松应对客户的特殊性,还可以提供可靠且有保证的有序通信。