UDP

来源:互联网 发布:新三板历年数据统计 编辑:程序博客网 时间:2024/05/22 10:48

一般的处理方式有以下2种情况:
一、服务器不需要保存客户端的上下文逻辑数据:
   这种情况处理起来比较简单,以下为大概的处理流程:
   1,ListenThread接收到数据后,把数据和对方的端口和IP插入数据包队列
   2,WorkThread线程处理数据包队列中的数据后把需要发送的数据插入发送队列
   3,SendThread发送数据给客户端

二、服务器需要保存客户端的上下文数据:
   这种情况下稍微比较复杂一点,如果可以用TCP就尽量用TCP,TCP比较简单一点
   一般的做法是给每个客户端分配一个唯一的ID(GUID),第一次和服务器通信时需要一个初始化的过程,
   类似TCP的握手操作,在服务端保存每个ID的上下问数据,这样服务器就可以识别每个客户端了。
   以上的方式还有些小问题,就是客户端发送数据的时候都需要带一个ID号,ID号一般都是比较长的字符
   串,在服务器上对数据进行分类的时候效率也不是很高,所以最好是用客户端的IP+PORT的整型数据作为
   KEY关联起来,这样在客户端的每个SOCKET需要定时的发心跳包服务端来保持客户端的外网端口不会比路
   器关闭。其它的细节就需要自己慢慢琢磨下了。

一、Libev对于网络高并发的优势

 

在调研初期,主要着眼于网络高并发,这样比较自然的查到了LibeventLibev。以Libev为例,它是一款高性能的时间循环库。Libev之所以长于解决网络高并发问题,主要是因为其支持epollselect等多路复用机制。以读取网络数据为例,简要分析epollselect的原理和区别。程序在读取数据之前,需要等待数据就绪。在select机制下,数据就绪之后,程序会被通知有数据就绪,但是并不知道是哪个文件描述符的数据就绪,需要遍历所有文件描述符,因此操作的时间复杂性是线性的;在epoll机制下,数据就绪后,程序不仅知道有数据就绪,而且可以知道是哪个文件描述符的数据就绪,因此操作时间是常数的。由于select的操作是线性复杂的,在使用select时,当文件描述符的数量较大后(一般以1024为界限),就需要再起额外的线程。而epoll的操作是常数的,所以无论有多少个文件描述符,都不影响其性能。不过,一般epoll仍然需要和多线程配合。常见的做法是,主进程通过epoll机制观察有无新的请求,当有新的请求,就由一个工作线程进行处理。

二、tcp并发与udp并发的区别

Libev适用于网络高并发,主要由于它支持epollselect等多路复用机制,加之与多线程配合,性能较好。但是无论是epoll还是select,在观察有无数据就绪时,都是针对多个文件描述符。如果只有一个文件描述符,那么进程只要观察那一个文件描述符即可。在网络编程中,一个Socket对应一个文件描述符。Tcp协议的server在监听端口前初始化一个socket,每有一个新的连接,就新建一个socket。因此当tcp服务器面对高并发请求时,实际上有多个socket,也就是有多个文件描述符。Libev适用于这种模式。Udp协议的Server没有真正意义上的连接的概念,在监听端口和响应请求时都只有一个socket,也就只有一个文件描述符。因此,对于udp服务器,Libev实际上意义不大。虽然Libev支持网络IO事件,也就支持udp协议,但是在udp socket中直接使用epoll意义不大,测试发现由于存在额外开销,将小幅度影响性能。

三、udp并发的常规思路

大部分udp服务器是顺序迭代的,服务器等待客户端请求,然后读取请求,处理请求,发回响应。但是,当处理客户端请求需要很长时间,就需要考虑某种形式的并发。一个长处理可以理解为处理请求的时间明显大于发送请求的时间。

并发的常见思路是使用多线程。服务器在读取一个新请求之后,可以交由一个线程处理,该线程在处理之后直接将响应内容发给客户端。另一方面,udp服务器和多个客户端交互,但是却没有多个socket。典型的解决方案是,服务器为每个客户端创建一个新的socket,并绑定一个新的端口。客户端以后就通过这个新的socket与服务器通信,获得响应。总结来说,udp并发服务器,针对多个客户端,可以创建多个socket;针对多个请求,可以使用多线程(线程池)进行处理。

四、本项目与高并发

      本项目需要实现一个udp服务器,其特点是多客户端,服务为短处理,需要进行写操作。解释一下短处理和写操作。第三部份有所阐述,在服务为长处理时,并发有其必要性。但是本项目是短处理,又需要加锁。这样来看,多线程并发就没有很强的必要性。另外Libev支持的多路复用机制主要针对互联网应用,动辄上万个并发连接。而项目属于节点通信,客户端预计在几十和上百之间。经过少量节点实验,加入Libev反而小幅度影响性能。因此,我准备不加入Libev和多线程,使用单线程实现系统。目前的demo系统,测试性能最佳。

    那不加并发能不能顶住流量压力呢?这最终还需要实验验证,不过我初步推断应该可以。我使用5个客户端(客户端数量偏少)模拟并发测试,每微秒发送一个请求,服务器出现少量丢包。真实环境是一个几百M的多媒体文件对应一个几byte的请求,这样的数据比例导致请求不会过于频繁。当有数据包丢失,也可以通过加入重传机制解决。

0 0
原创粉丝点击