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

多线程udp服务器

南宫才艺
2023-03-14

我是个新手,如果你能给我建议的话,请告诉我。我有一个向客户端广播消息的服务器。然后客户端将回复发送回服务器。我想用单独的线程处理每个回复。每个回复都有mesage id和thread id。我如何用来自所有线程的信息填充一些结构,然后读取它

也从我的代码,它是正确地创建线程,而还是它存在某种方式来创建线程,只是如果我得到客户端的回复?

我是从正确的理解开始的吗?

int main(){

    while(1){

        sendto on broadcast IP 
        pthread_create(&cln_thread, NULL, msg_processing, (void *) &arg))

   }
}

msg_processing () {

     recvfrom client msg with id of packet and thread id
     how to write those informations and then read them in main when program finish

}

非常感谢。

共有2个答案

邓德本
2023-03-14

您可以在Go lang中找到一个多线程UDP服务器的好例子,如下所示:https://gist.github.com/jtblin/18df559cf14438223f93

主要思想是完整地使用多核功能,以便每个线程在自己的CPU核心上工作,并将UDP数据读取到单个缓冲区中进行处理。

郎曾笑
2023-03-14

犯错误不,只需创建一个线程,仅一次,用于在一个套接字上接收数据报。在线程函数中,在while(true)循环中接收数据报。不要让此接收线程终止,也不要再创建任何接收线程。不断地创建/终止/销毁线程是低效的、危险的、不必要的、容易出错的、难以调试的,您应该尽最大努力避免这样做。

编辑:

只有一个接收线程-但您不必在那里进行处理。Malloc一个64K的缓冲区,接收数据,将缓冲区指针推到生产者-消费者队列上,推到一个线程池中,该线程池将进行处理,循环返回,然后Malloc再次重置指针,并为下一个数据报创建另一个缓冲区。处理完成后,释放池线程中的*缓冲区。当缓冲区处理并行运行时,接收线程将返回等待数据报。

如果您发现数据报到达得如此之快,以至于处理跟不上,随着队列中堆积越来越多的*缓冲区,内存使用将不受检查地增长。有几种方法可以解决这个问题。您可以使用一个有界队列,该队列在达到其容量时进行阻塞。您可以在启动时创建x缓冲区,并将其存储在接收线程弹出的另一个生产者-消费者“池队列”上(而不是malloc)-处理池线程可以将“使用”*缓冲区推回到池队列中重用。如果池用完,接收线程将阻塞池,直到返回*缓冲区。

我更喜欢池缓冲区方法,因为它限制了整个系统的内存使用,避免了连续的malloc/free和碎片问题等,避免了更复杂的有界队列,更容易调整(池级别在运行时很容易更改),更容易监控/调试-我通常转储池级别(即队列计数),使用计时器每秒显示一次。

无论哪种情况,数据报都可能丢失,但是,如果您的系统过载,以至于数据定期到达的速度快于处理速度,无论您如何设计,情况都会如此。

一个插座就可以了,那么为什么要复杂化呢?:)

 类似资料:
  • 我有两个线程,一个在一个套接字上监听并添加到队列中,另一个从队列中减去并提交处理。第二个线程在队列为空时Hibernate。这个睡眠不知怎么会影响第一个线程,也就是说,如果您移除睡眠或使它变大,那么第一个线程的socket.receive中的延迟就会增加。如果我保持尽可能低的睡眠,它会变得更好,但不是完美的。我做错了什么?

  • 为了实现这一点,我使用了队列/线程池机制。最初,我创建一个固定数量线程的池,并有一个队列datastructure来存储客户机地址。这个队列在所有线程之间共享,因此我使用“互斥”来锁定/解锁这个队列。在主服务器线程中,我创建一个套接字,将其绑定到全局端口/地址,然后在“recvfrom”调用上阻止服务器。任何希望与服务器通信的客户端都会向侦听全局端口地址的主线程服务器发送“HI”消息。主服务器线程

  • 我正在尝试基于Netty构建一个UDP服务器,以便根据客户端订阅(在订阅设置之前交换一些UDP请求/响应消息)将事件(大约每秒500个事件)连续发布到不同的客户端。 设计是由Java执行器创建一些生产者/消费者线程。生成消息后,使用者线程将其写入UDP通道。 观察到,服务器端只有一个EventLoop线程在为该UDP通道工作,并且它非常忙于向套接字写入消息,因此对第二个和更高版本客户端的订阅请求的

  • 程序代码 udp_server.php //创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP $serv = new Swoole\Server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); //监听数据接收事件 $serv->on('Packet', function ($serv,

  • 服务器 用于监听服务器中每个客户机的线程在名为OyenteCliente(ClientListener)的类中实现,每个客户机中监听服务器petitios的线程在OyenteServidor(ServerListener)中实现。 客户监听器 非常感谢!