接收来自 N 个客户端的响应,以回复通过 UDP 的广播请求
我正在为特定类型的网络多媒体设备实现一种 IP 查找器。 我想找出 LAN 中该类型的所有活动设备及其 IP 地址和其他详细信息。
设备有自己的设备发现方式。
其工作原理如下: 客户端通过 UDP 通过 LAN 发送广播请求。
目的端口号是固定的。
作为答复,LAN 中所有理解该请求格式的服务器都将响应该请求并提供有关其自身的信息。
我正在使用 sendto() 广播 UDP 请求消息。
现在我的问题是我不知道有多少设备(即服务器)会响应该请求。
我需要调用recvfrom()多少次?
我什么时候才能知道我已经处理了所有设备的响应?
或者一般来说,recvfrom() 是从多个服务器接收响应的正确选择吗?
有没有更好的(或者正确的,如果我在这里错了)方法来完成同样的任务?
我正在使用 C/C++ 进行编程,计划为 Windows 和 Linux 编写代码。
非常感谢。
编辑: 因此,在所有网络编程向导的帮助下,我找到了问题的解决方案:)
select() 正是适合我的东西......
非常感谢大家抽出时间来帮助我
I am implementing a kind of IP finder for a particular type of network multimedia device.
I want to find out all the alive devices of that type in the LAN, with their IP address and other details.
The device has its own way of device discovery.
It works as follows:
A client sends a broadcast request over the LAN via UDP.
The destination port number is fixed.
In reply, all the servers in the LAN that understand the format of this request will respond to this request providing information about themselves.
I am broadcasting the UDP request message using sendto().
Now my problem is that I don't know how many devices (i.e.servers) will respond to the request.
How many times will I have to call recvfrom()?
When will I come to know that I have handled the response from all the devices?
Or in general, is recvfrom() the right choice for receiving response from multiple servers?
Is there any better (or CORRECT if I am wrong here) way of accomplishing the same?
I am programming in C/C++, planning to code for both Windows and Linux.
Many thanks in advance.
Edit:
So with the help of all the network programming wizards out here, I have found the solution to my problem :)
select() is just the thing for me...
Thanks a lot to all of you who took out time to help me
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您不知道设备/服务器的数量,则无法知道需要调用
recvfrom()
多少次或何时处理完所有响应。您可以考虑使用
select()
循环(直到超时),并在数据可供读取时调用recvfrom()
。这可能在主线程或单独的线程中。如果数据到达的速度快于处理的速度,您将丢失数据报。这很大程度上取决于接收数据后解析和存储数据的速度。如果处理数据是密集型操作,则可能需要在单独的线程中进行处理或存储数据直到接收循环超时,然后继续处理它。
由于 UDP 不可靠,循环重播几次应该有助于解决一些丢失问题,并且处理应该解决重复问题。
以下伪代码是我解决该问题的方法:
recvfrom()
通常与无连接模式套接字一起使用,因为它允许应用程序检索接收到的数据的源地址。If you don't know the number of devices/servers, you cannot know how many times you will need to call
recvfrom()
or when you've handled all the responses.You might consider using a
select()
loop (until timeout) and callrecvfrom()
when data is available to read. This might be in the main thread or a separate thread.If the data arrives faster than it can be processed, you will lose datagrams. This will depend largely on the speed that the data is parsed and stored after it is received. If processing the data is an intensive operation, it may be necessary to do the processing in a separate thread or store the data until the receive loop times out and then proceed with processing it.
Since UDP is unreliable, looping to rebroadcast a few times should help account for some of the loss and the processing should account for duplicates.
The following pseudocode is how I might approach the problem:
recvfrom()
is commonly used with connectionless-mode sockets because it permits the application to retrieve the source address of received data.在循环中使用带有超时的
select(2)/poll(2)
,每次从设备收到响应时都会减少超时。你必须自己想出适当的暂停时间。或者,如果您能够识别/解析发现响应消息,只需在收到此类消息后将设备添加到列表中即可。
当设备注册但稍后失败时,您可能必须处理超时问题。
Use a
select(2)/poll(2)
with a timeout in a loop, decrementing the timeout every time you get a response from a device. You'd have to come up with appropriate timeout yourself.Alternatively, if you are able to recognize/parse the discovery response message, just add the device to the list upon receiving such message.
You will probably have to deal with timeouts anyway for when devices register but fail at a later point.
如果你不知道有多少服务器将响应,那么你就不知道要调用recvfrom()多少次。我可能会使用带有合适超时的 select() 循环来处理这个问题,如下所示,它完全未经测试,并且可能充满了愚蠢的错误:
这将继续调用 recvfrom() 直到 2 秒内没有收到回复,这当然意味着它会阻塞至少 2 秒。根据底层协议,您可能可以得到更短的超时;事实上,你可以在每次响应时减少它。需要进行一些测试和调整才能找到最佳配置。您无需担心服务器同时响应;以太网层将处理这个问题。
If you don't know how many servers are going to respond, then you don't know how many times you have to call recvfrom(). I would probably handle this with a select() loop with a suitable timeout, something like the following, which is completely untested and probably full of stupid bugs:
This will keep calling recvfrom() until no reply has been received for 2 seconds, which of course means that it will block for a minimum of 2 seconds. Depending on the underlying protocol, you can probably get away with a much shorter timeout; indeed you can decrease it on each response. Some testing and tuning will be required to find the optimum configuration. You don't need to worry about servers responding at the same time; the Ethernet layer will handle that.
你不可能知道。其不可知。
据推测,根据您的描述:
我想找出所有活动的设备
,这些设备可以随时从死亡状态转变为活着状态,然后再返回。这意味着您必须连续轮询:即每隔几秒(但不要太频繁)发送广播请求并查看谁响应。如果我的理解正确,那么 UDP 本质上是不可靠的,那么您将不得不在 UDP 之上改进一些可靠性:
您知道可能的设备数量上限吗?如果你这样做,你可能会发现你必须多次调用recvfrom()。
You can't know. Its unknowable.
Presumably, from your description:
I want to find out all the alive devices
, the devices can transition from dead to alive and back again any time they want to. This means that you will have to poll continuously: ie send the broadcast request every few seconds (but not too often) and see who responds.If I've got this right, that UDP is inherently unreliable, you are going to have to retro-fit some reliability on top of UDP:
Do you know the maximum number of possible devices? If you do you may find that you have to call recvfrom() that many times.