简体   繁体   English

Unix:recvfrom()

[英]Unix: recvfrom( )

How to receive message from only desired client if I know that this client has been connected to my server? 如果我知道此客户端已连接到服务器,如何仅从所需的客户端接收消息?

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

addr will be replaced by corresponding data, but I want receive data from only one client addr将被相应的数据替换,但是我只想从一个客户端接收数据

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

if(addr.sin_addr.s_addr == "ADDRESS_OF_DESIRED_CLIENT")
{
//ALLOW USER
}

For IPV4 "addr.sin_addr.s_addr" is an int, but you can also get the Address in a string from. 对于IPV4,“ addr.sin_addr.s_addr”是一个整数,但是您也可以从字符串中获取地址。

How to receive message from only desired client if I know that this client has been connected to my server? 如果我知道此客户端已连接到服务器,如何仅从所需的客户端接收消息?

You can't really do this with a datagram socket in the AF_INET or AF_INET6 family, unless undesired clients are blocked at a lower level, such as via a firewall. 您实际上不能使用AF_INETAF_INET6系列中的数据报套接字执行此操作,除非将不需要的客户端阻止在较低级别(例如,通过防火墙)。 At least, not if you want to be able to continue to receive messages from desired clients after one from an undesired client arrives. 至少,如果您希望在来自不希望的客户端的邮件到达后能够继续从所需的客户端接收邮件,则不是这样。 The network driver queues datagrams for you, and you need to handle them in order, where the C API for "handling" a datagram is to receive it via one of the several system calls that serve that purpose, such as recvfrom() . 网络驱动程序为您排队数据报,并且您需要按顺序处理它们,其中用于“处理”数据报的C API将通过为此目的服务的几个系统调用之一来接收数据报,例如recvfrom()

You can discriminate between messages after receiving them, such as by discarding those from undesired clients. 您可以接收到消息对其进行区分,例如通过丢弃不希望的客户端发送的消息。 However, it is of limited, special-purpose use to retrieve message data without dequeueing it, as the MSG_PEEK flag to recvfrom() provides. 但是,它具有有限的特殊用途,可以在不使消息出队的情况下检索消息数据,就像recvfrom()MSG_PEEK标志所提供的那样。 In particular, that does not serve your stated purpose -- you will still need to receive every message, via a subsequent call that does not use MSG_PEEK . 特别是,这不符合您指定的目的-您仍然需要通过不使用MSG_PEEK的后续调用来接收所有消息。 Instead, I suggest simply reading the data via recvfrom() , checking the address to determine whether it's from the client you're interested in, and handling it appropriately. 相反,我建议您仅通过recvfrom()读取数据,检查地址以确定它是否来自您感兴趣的客户端,并进行适当处理。

If you want to handle multiple clients at the same time, then you have some alternatives. 如果要同时处理多个客户端,则有一些替代方法。 A relatively simple one is to have a function, perhaps running in a dedicated thread, that receives all incoming messages and dispatches them appropriately according to their source addresses. 一个相对简单的功能是拥有一个可能在专用线程中运行的功能,该功能可以接收所有传入的消息并根据其源地址适当地分派它们。 Another alternative is to open a new (datagram) socket for each client, each on its own port, and to set up a protocol by which you tell each client which port to use after their first contact. 另一种选择是为每个客户端打开一个新的(数据报)套接字,每个套接字都在其自己的端口上,并设置一个协议,通过该协议,您可以告诉每个客户端在首次联系后要使用哪个端口。 Datagrams from unexpected clients on these additional ports would be erroneous, and therefore safe to reject. 来自这些其他端口上的意外客户端的数据报将是错误的,因此可以安全地拒绝。

Of course, the latter of those is an approximation to a connection-oriented protocol. 当然,后者是近似于面向连接的协议。 If it seems attractive to you then perhaps you should be looking at stream sockets instead of datagram sockets. 如果它对您似乎有吸引力,那么也许您应该看一下流套接字而不是数据报套接字。 Not only would that get you no-fuss client specificity, it would also provide for reliable and guaranteed in-order communication. 这不仅可以让您毫不费力地实现客户专用性,还可以提供可靠且有保证的有序通信。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM