[转载]UDP丢包率提高

UDP丢包及无序问题

转载自:http://hi.baidu.com/gamedot/item/96cb9bf1a717eb14d6ff8cd5面试

最近在作一个项目,在这以前,作了个验证程序. 
发现客户端连续发来1000个1024字节的包,服务器端出现了丢包现象. 
纠其缘由,是服务端在还未彻底处理掉数据,客户端已经数据发送完毕且关闭了. 

有没有成熟的解决方案来解决这个问题. 
我用过sleep(1),暂时解决这个问题,可是这不是根本解决办法,若是数据量大而多,网络状况不太好的话,仍是有可能丢失.算法

 

你试着用阻塞模式吧... 
select...我开始的时候好像也遇到过..不过改成阻塞模式后就没这个问题了...编程

 

采用回包机制,每一个发包必须收到回包后再发下一个缓存

 

UDP丢包是正常现象,由于它是不安全的。安全

 

丢包的缘由我想并非“服务端在还未彻底处理掉数据,客户端已经数据发送完毕且关闭了”,而是服务器端的socket接收缓存满了(udp没有流量控制,所以发送速度比接收速度快,很容易出现这种状况),而后系统就会将后来收到的包丢弃。你能够尝试用setsockopt()将接收缓存(SO_RCVBUF)加大看看能不能解决问题。服务器

 

服务端采用多线程pthread接包处理网络

 

UDP是无链接的,面向消息的数据传输协议,与TCP相比,有两个致命的缺点,一是数据包容易丢失,二是数据包无序。 
要实现文件的可靠传输,就必须在上层对数据丢包和乱序做特殊处理,必需要有要有丢包重发机制和超时机制。 
常见的可靠传输算法有模拟TCP协议,重发请求(ARQ)协议,它又可分为连续ARQ协议、选择重发ARQ协议、滑动窗口协议等等。 
若是只是小规模程序,也能够本身实现丢包处理,原理基本上就是给文件分块,每一个数据包的头部添加一个惟一标识序号的ID值,当接收的包头部ID不是指望中的ID号,则断定丢包,将丢包ID发回服务端,服务器端接到丢包响应则重发丢失的数据包。 
模拟TCP协议也相对简单,3次握手的思想对丢包处理颇有帮助。多线程

 

udp是不安全的,若是不加任何控制,不只会丢失包,还可能收到包的顺序和发送包的顺序不同。这个必须在本身程序中加以控制才行。 
收到包后,要返回一个应答,若是发送端在必定时间内没有收到应答,则要重发。socket

UDP原本存在丢包现象,如今的解决方案暂时考虑双方增长握手. 
这样作起来,就是UDP协议里面加上了TCP的实现方法. 
程序中采用的是pthread处理,丢包率时大时小,不稳定可靠性能

 

我感受缘由可能有两个,一个是客户端发送过快,网络情况很差或者超过服务器接收速度,就会丢包。 
第二个缘由是服务器收到包后,还要进行一些处理,而这段时间客户端发送的包没有去收,形成丢包。 

解决方法,一个是客户端下降发送速度,能够等待回包,或者加一些延迟。 
二是,服务器部分单独开一个线程,去接收UDP数据,存放在一个缓冲区中,又另外的线程去处理收到的数据,尽可能减小由于处理数据延时形成的丢包。

 

有两种方法解决楼主的问题: 
方法一:从新设计一下协议,增长接收确认超时重发。(推荐) 
方法二:在接收方,将通讯和处理分开,增长个应用缓冲区;若是有须要增长接收socket的系统缓冲区。(本方法不能从根本解决问题,只能改善)

 

网络丢包,是再正常不过的了。 
既然用UDP,就要接受丢包的现实,不然请用TCP。 
若是必须使用UDP,并且丢包又是不能接受的,只好本身实现确认和重传,说白了,就是本身实现TCP(固然是部分和有限的简单实现)。

 

UDP是而向无链接的,用户在实施UDP编程时,必须制定上层的协议,包括流控制,简单的超时和重传机制,若是不要求是实时数据,我想TCP可能会更适合你!

huangcanbao 发表于Tuesday, September 22, 2009 7:33:22 PM  IP:
今天接到了电话面试,还好个人解决方案和你这位朋友的同样。1:给本身发的数据定义协议,序号 大小 数据。 2:传输过程都要进行双方验证,是否接受到正确的数据。根据传输的字节大小来管理的。
转自 http://blog.csdn.net/yylklshmyt20090217/archive/2009/06/17/4275937.aspx
建议的办法是,对于大的报文本身进行一个分包和组包操做.要减小丢包率(丢包重发,一样是不小的消耗),把单包的大小定在1500字节之内,按24MBit/s的带宽最大流通量2048个包每秒,这个压力是至关小的.
丢包是很正常的,发包越大丢包的可能性就越高,与网卡速度没有必然联系,须要本身设计应答和重发机制。至于多大的数据包最合适,要在实际运行的环境中测试才能知道。程序运行过程当中能够本身统计并计算丢包率,而后动态调整数据包的大小来适应运行环境。
另外是内存池这些,最简单的,你要是每次new char[1024]再去收,那收线程速度就当下来了. 

记住,收线程不要作任何事.那怕只查个MAP,在上万包每秒时,每秒的操做就上万个MAP查询, 


另外丢包多是发送端,发出来已经丢了,你要考虑发送的的发送处理,发送处理写得很差,其实发 

的过程根本没机会出网卡缓冲,就已经丢了有可能. 

中间路由器环节(这个没法控制,只能看看这个环节性能如何)
相关文章
相关标签/搜索