当前位置: 首页 > 知识库问答 >
问题:

UDP服务器,如何做到每个线程都能接收正确的客户端数据包而不是其他线程?

怀宇
2023-03-14

嗯,我必须在linux上用C做一个udp服务器

这是我的问题,例如:我知道每个线程将管理一个客户机。但是recvfrom将接受来自任何源的数据包,那么,如何才能使每个线程都能接收正确的客户端数据包,而不是其他线程?

我希望我能很好地解释我的问题。

非常感谢。

(我的意思是,我的服务器将为每个需要服务的客户端创建一个新线程。因此,对于TCP,我可以使用accept为每个线程客户端连接创建一个“专用”套接字,但对于UDP,我不能这样做。)

共有3个答案

令狐运珧
2023-03-14

这就是为什么你有一个端口号。

如果您的服务器正在侦听端口8080,则不允许其他进程将套接字绑定到该端口。

所有想要连接到此服务器的客户端都需要将其数据发送到服务器IP上的端口8080。

充修能
2023-03-14

UDP是一种基于消息的无连接协议。在这里,在发送数据之前,客户端和服务器之间没有明确的连接/设置。它不维护客户端或服务器上的任何通信状态。UDP使用数据报套接字(SOCK_DGRAM)。这确保每个数据包以任何顺序发送或接收,但保留消息边界。

TCP是一种基于流的面向连接的协议。这里,在数据交换之前,客户端和服务器之间建立了明确的逻辑连接。TCP状态被维护用于通信。TCP使用流套接字(SOCK_STREAM)。这提供了面向连接的有序数据流,具有创建/释放连接和检测错误的机制。

在TCP和UDP的标头中,只显示端口号。IP报头负责为路由添加必要的目标IP地址。但是,应从源主机获取源ip地址。

在TCP服务器和UDP服务器中,一旦使用特定套接字类型创建了套接字,就会使用绑定系统调用将其绑定到端口。这样做是为了客户机可以将地址发送到服务器的这个端口。绑定过程在TCP客户机或UDP客户机中都不是必需的,因为它在客户机通信的任何端口中都无关紧要。到目前为止,TCP服务器和UDP服务器都是相同的。

对于TCP服务器,将调用listen系统调用来侦听特定套接字上的连接。侦听指示可以排队的连接数限制,并且服务器进程已准备好接受套接字上的任何新传入连接。服务器调用accept系统调用,该调用是等待传入连接的阻塞调用。一旦出现新连接,就会创建一个新的套接字描述符,并在服务器和客户端之间建立连接。但是,作为服务器,它必须不断侦听新的连接。这就是多重处理开始进入画面的地方。由于任何客户端都可以在任何时候通过使用connect系统调用触发连接,因此我们需要为新连接设置accept调用(阻塞调用)。此外,要并行处理这些新连接,一个选项是分叉并创建一个子进程,该子进程将在父进程等待accept调用时进一步处理新连接。这就是在服务器中识别和处理/处理单个客户端连接的方式。简单地说,在并发服务器体系结构中,服务器上随时都会有一个侦听套接字和多个连接的套接字endpoint。

注意:来自客户端的connect系统调用触发来自客户端的TCP SYN,用于启动3路握手过程。此时,客户端套接字状态为SYN_SENT,一旦SYN到达服务器,服务器套接字状态为SYN_RCVD。然后,服务器向客户机发送SYN_ACK,客户机将向客户机发送ACK,从而建立客户机和服务器之间的连接。

在UDP服务器的情况下,不需要初始连接建立,因为它是一个使用数据报套接字(SOCK_DGRAM)的基于消息的无连接协议。因此,UDP客户端将不需要连接调用来建立连接,这将减少UDP服务器中侦听和接受调用的需要。因此,UDP客户机-服务器体系结构应为迭代体系结构,其中每个客户机请求/响应应按顺序处理,因为迭代服务器体系结构适用于消耗较少处理时间的UDP(轻量级)等服务。还要注意的是,由于处理所消耗的时间较少,迭代服务器的状态也会较少。

在需要多个线程监听同一个套接字的情况下,您也可以选择基于软件架构的选择或电子投票系统调用,其中每个线程都将等待选择调用,但在这种情况下,它可能没有很大的帮助。可以满足您需求的另一种设计可以是用于接收、解析的单独线程的组合

公冶谦
2023-03-14

不能让多个线程同时从同一个套接字读取数据。

你应该做的是:

>

  • 有一个专用线程,它接收所有入站数据包,查看源IP/Port,并根据需要将数据路由到适当的处理线程。

    给每个处理线程自己的套接字,该套接字是绑定()'ed到相同的本地IP/Port和连接()'ed到它感兴趣的特定源IP/Port,然后每个线程可以调用recvfrom()它将只返回与线程期望的源相匹配的数据包。

  •  类似资料:
    • 我的问题是关于以下场景中的客户机-服务器通信。 服务器侦听端口21,能够同时为来自客户端(C1、C2等)的多个传入连接提供服务,而不会阻塞它们 因此,当客户机C1连接到端口21上的服务器S时,服务器接受主线程上的连接,并创建一个新的线程TH1,让它处理客户机请求,同时主线程再次开始列表到端口21以接受新的客户机。 TH1将一些数据发送回客户端C1,C1将恢复数据,并在端口21上建立的同一连接上向服

    • 使用套接字列表编辑: 按照EJP的建议,这样做我的问题就解决了。

    • 我想做的是: 为了学习游戏编程,我使用专用服务器和UDP创建了一个回声设置。专用服务器在不同的城市(也就是不在我的本地网络中)。 在我的本地计算机上,我有一个udp客户端和服务器(两个不同的程序)。当我第一次启动python服务器时,windows防火墙立即询问我是否要添加异常。在允许我的python服务器联网之后,我仍然没有收到任何消息。(客户- 我的问题是: 游戏如何解决这个问题?我没有为我想

    • 我正在尝试使用UDP在服务器(在公共IP上)和客户端(通过NAT)之间进行双向通信。我的逻辑是,如果服务器向IP和它接收数据包的端口发送一些数据,客户端仍然应该得到它,因为NAT最终会有将数据包发送到客户端的映射。 客户端有 2 个进程,一个用于发送数据包,另一个进程用于接收数据。服务器继续等待数据,如果它获得数据,它会将数据发送回从接收数据的端口和 IP。 客户代码如下: client_recv

    • 当多个客户端向服务器发送数据包时,我如何编写代码在其相应的子线程上接收数据包,而不是在主进程上接收数据包 我正在使用线程为udp客户端和服务器编写c程序,所以如果我有4个客户端连接,将创建4个线程,每个线程将发送一些数据。在接收到数据之后,客户端将发送ACK,但问题是这些ACK应该由相应的线程接收,但是 我在主进程中有receivefrom函数来监听新的客户端,我在线程上也有receivefrom

    • 客户端-NAT后面的Windows桌面,运行UDP客户端应用程序。 服务器-具有公共IP的Ubuntu服务器,运行一个UDP服务器应用程序,该应用程序期望在端口6000上发送数据包。 ClientPrivate/Public-客户端的私有/公共IP 服务器私有/公共 - 服务器的私有/公共 IP 客户端打开一个UDP套接字Client私人: 777和发送数据报Server公共: 6000 服务器从