多个UDP套接字和多个客户端

时间:2017-08-27 10:56:34

标签: sockets udp client-server

我必须使用UDP套接字编写一个程序,而且我无法理解在我的场景中应该做些什么。

我有一台服务器和一台客户端。服务器在INADDR_ANY套接字上接收数据报,并且对于显示的每个唯一客户端,它将向()发送大量信息。每个客户端还定期向服务器发送数据。

对于每个联系监听套接字的客户端,我们称之为0,我为其创建一个单独的套接字,这样我就可以在不堵塞套接字0的情况下向其发送数据。我想做的是将所有与特定客户端的通信移动到新的插座。我能这样做吗?目标是使通信更容易,更有效,并避免堵塞任何插座。

所以我找不到答案的问题是:

  • 我可以从该特定客户端的套接字中恢复数据吗?
  • 如果没有,如果我不经常回收,不会让所有客户端写入套接字0阻塞吗?
  • 如果可以从单独的套接字上的特定客户端重新获取数据,那么该数据是否会转到BOTH套接字0和特定套接字?

我知道TCP会更好用,但我必须使用UDP。我该怎么做?是否有处理此类情况的公认“标准”?

评论:我有一种感觉,我误解了UDP套接字,但与TCP相比,它上面的教程非常少。

2 个答案:

答案 0 :(得分:3)

  

我想要做的是将与特定客户的所有通信转移到   新的插座。我能这样做吗?

您可以创建一个新的UDP套接字,将其绑定()到另一个端口,然后指示客户端开始将流量发送到新套接字的端口而不是通常的端口;但请注意,通过这样做可以获得任何优势。

  

如果没有,不让所有客户端写入套接字0阻塞它,如果我   不会经常回收吗?

是的,但是调用recvfrom()的常用解决方案通常足以跟上传入流量的流量,和/或增加其SO_RECVBUF缓冲区大小以使其传入数据缓冲区足够大以至于它是不可能的变满了。 确保recvfrom()被调用的一种方法就是创建一个单独的线程,除了在循环中调用recvfrom()之外什么都不做,然后将数据移交给另一个线程以进行更密集的处理。如果可能的话,以更高的优先级运行此网络线程,以确保它不被其他线程阻止。

  

如果可以在单独的客户端上从特定客户端收回数据   socket,那个数据会来到BOTH套接字0和特定套接字吗?

如果你有两个线程都在同一个套接字上调用recvfrom(),那么任何给定的传入UDP数据包将被传递到一个线程或另一个线程,并且无法预测哪个线程将接收哪个数据包 - 这将是抽奖的好运,这取决于特定线程在其上调用recvfrom()的瞬间,套接字的传入缓冲区中的下一个数据包是什么。通常,多线程访问单个套接字不是推荐的设计。

  

我知道TCP会更好用,但我必须使用UDP。怎么样   我应该这样做吗?是否有接受的标准"处理这样的   的情况?

我不知道"标准"是什么,但我通常有一个专用的I / O线程,除了从UDP套接字读取(如果需要,写入)之外什么都不做。它将UDP套接字设置为非阻塞模式,然后循环select()到recvfrom()任何传入的UDP数据包,并附加(以线程安全的方式)传入数据包的数据及其源地址/端口信息到FIFO队列,以便其他(时间较不敏感)线程取出并稍后处理。这样,即使数据包(或系列或数据包)需要相对较长的时间来处理,结果也会导致数据包丢失(尽管随着FIFO变大,它可能会暂时增加RAM使用率)

答案 1 :(得分:0)

@ Jeremy Friesner:您写道:“...即使如此,我的直觉是,这两个套接字中的哪一个接收任何特定数据包将是不确定的/不可预测的——如果您的 connect() 套接字接收其他人的数据包,我怀疑数据包会被丢弃/过滤”。 正是这一点,我在 Linux 和 lwIP 中进行了调查,结果是:后来创建的套接字(具有更高的 fd 编号)是接收一个,而另一个不接收。

相关问题