udp重发

最近在处理框架通讯方面的问题,通过积累的开发经验,其实在很多情况(尤其是实时大数据量),udp是占有很多优势的;不需要连接,只管发送,理论上要快很多;

另外在穿墙上占有很大优势;

但是最大的一个问题就是丢包;

很多时候我们会结合我们的业务来进行发送与回执,这样的方式应该的最好的;但是也意味着每次都得重来一次;因此花费了一些时间来写这个重发逻辑;当然目前仅是测试;

封装了一个udp重发;其实组播也可以直接使用,只是我还没有完成封装,原来一样,只不过组播封装重发,会浪费网络资源,只要一个节点(把一个接收位置看作一个节点)没有收到其中一个包,就需要发送端发送,所有节点都会接收(并不影响数据完整,在接收已经封装了接收发生,不会造成数据重复);不说组播了,回到udp重发;

大体结构:

1.每一次发送都视为session;

1》judpclient为封装的发送端,发送数据时,会自动分包,按照udp65535大小(可以设置);每次发送分配一个发送端session(同时产生id),每次发送分包时,都会依次产生

一个初始化序列号,按照初始序列号,每包设置一个id,按照此发送打包数据发送

2》同时会发送一个ack发送确认包,防止数据包只有一个被丢包;

3》发送后等待数据返回

4》judpclient关闭只是逻辑关闭

2.接收端

接收端按照来源IP,端口产生一个接收端session,然后接收数据,组织数据,检查丢包,发送丢包ack;

接收端设计了serversession及buffer,所以不用担心数据重发造成数据触发的问题,该结构读取方式已经直接避免了

3.辅助应用

因为是辅助,无法判断judpclient使用情况,所所以利用java特点,在回收对象时设置逻辑关闭;同时控制时间,来判断通讯真实关闭(因为发送端还要监听等待重发)

4.共享session

最开始的设计是不共享的,但是在测试时发现,在极端时候,因为发送端占有端口监听需要时间,重新初始化judpclient对象,会导致端口占用完,无法再分配;所以

最好采用了共用的方式,让多个judpclient实际使用一个真正的udp底层通讯;每个judpclient产生一个id,来判断数据接收时往哪里发送,触发哪个对象的方法;

5.缓存问题解决方式

数据重发就意味着发送的数据需要缓存下来,准备重新发送;这样如果发送大量数据,发送端就可能“爆满”,所以要减少内存使用;

处理方式:做一个简单的数据量统计(不精确,也不需要精确),当这个量达到一定值后,就把数据由内存转移到磁盘中;

我自己设计了一个文件保存方式(做了一个文件持久化层),来按照一定方式保存,也实现了文件删除,修改(修改没有必要);

里面主要是有个索引维护;同时使用了内存数据库表(如果不实现文件修改是没有必要的,通过异步方式保证文件索引准确,又不影响使用效率)

最开始我没有使用文件,而是查找了数据库(paldb,fastdb,mapdb等等),但是效果不尽人意,通过磁盘,其实一般磁盘读取在30M/s,而数据库是做不到的;因此我直接采用了文件读取方式;我并不是要做一个文件数据库,所以在实现文件修改时,任然使用了第三方数据库h2,简单直接,索引使用足够了,而且是异步;在数据重发这里,文件修正是没有必要的,实现该功能只是想让模块更加完整而已;

文件保存,也是通过一个简单的计数,每次10M左右的数据一起写入文件;

当接收端数据接收完成后,会回复一个接收完成ack包,发送端解析信息后,会把接收完成的一次会话数据都删除掉;

使用数据库保存的最初代码我并没有删除,只是没有使用而已;

6.遗留问题(需要优化)

通过什么的构造,其实最大问题在于我无法控制judpclient的使用,这样会造成很多线程启动,在监听数据返回的信息(丢包,完成),这样造成大量线程存在,虽然应用了线程池

根据现在的测试,发送端cpu 15-35%都是有可能的;阻塞的线程也很多,一旦彻底完成发送,同时退出的线程同样多,但是感觉这样也没有影响测试使用(可能是我的java水平不过关,有的测试结果我感觉很怪);所以需要缩减线程以及阻塞集合;

7.共享session分配

专门有个管理池分配,其实就是定一个最大个数,使用完了就再产生一个,同时监视是否共享session关闭情况

8.其它辅助实现

使用了guava的缓存及eventbus;

数据发送打包与解析配套(接收端也可以正常使用)

9.源码

eclipse编译;现在已经上传git;

地址:https://github.com/jinyuttt/jyudp.git

我也会上传到csdn,不过可能超过大小;

时间: 2024-10-03 07:44:56

udp重发的相关文章

NFS 性能管理指南

NFS 性能调优 在 NFS 网络中,服务器是调优的主要目标,当然也有一些是可以在客户机上调优的. 需要多少 biod 和 nfsd 守护进程? 因为 biod 和 nfsd 守护进程一次处理一个请求,并且 NFS 响应时间占了总响应时间的最大一部分,所以如果线程由于缺少 biod 或 nfsd 守护进程而阻塞是让人无法接受的. 注: 只存在单一的 nfsd 守护进程和单一的 biod 守护进程,它们都是多线程的(多个内核线程在一个进程里).此外,线程数是动调优的,会按需建立额外的线程.但是,您

TCP,UDP,HTTP,IP,SOCKET

近日对各网络协议进行了一番学习,宏观认识上有收获. 网络由下往上分为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层.(引用)IP 协议对应于网络层,TCP/UDP协议对应于传输层, HTTP协议对应于应用层, SOCKET则是对TCP/IP协议的封装和应用. TCP连接的三次握手:第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn

理解TCP和UDP协议

目录 TCP 协议 UDP协议 TCP和UDP的区别 TCP和UDP的使用场景 一 TCP协议 1.TCP的头部格式 理解TCP协议,首要的就是TCP协议的头部格式 ·        Source Port和Destination Port:分别占用16位,表示源端口号和目的端口号:用于区别主机中的不同进程,而IP地址是用来区分不同的主机的,源端口号和目的端口号配合上IP首部中的源IP地址和目的IP地址就能唯一的确定一个TCP连接: ·        Sequence Number:用来标识从T

UDP Socket

UDP的Java支持 UDP协议提供的服务不同于TCP协议的端到端服务,它是面向非连接的,属不可靠协议,UDP套接字在使用前不需要进行连接.实际上,UDP协议只实现了两个功能: 1)在IP协议的基础上添加了端口: 2)对传输过程中可能产生的数据错误进行了检测,并抛弃已经损坏的数据. Java通过DatagramPacket类和DatagramSocket类来使用UDP套接字,客户端和服务器端都通过DatagramSocket的send()方法和receive()方法来发送和接收数据,用Datag

Linux编程之UDP SOCKET全攻略

这篇文章将对linux下udp socket编程重要知识点进行总结,无论是开发人员应知应会的,还是说udp socket的一些偏僻知识点,本文都会讲到.尽可能做到,读了一篇文章之后,大家对udp socket有一个比较全面的认识.本文分为两个专题,第一个是常用的upd socket框架,第二个是一些udp socket并不常用但又相当重要的知识点. 一.基本的udp socket编程 1. UDP编程框架要使用UDP协议进行程序开发,我们必须首先得理解什么是什么是UDP?这里简单概括一下. UD

UDP协议开发

UDP是用户数据报协议(User Datagram Protocol,UDP)的简称,其主要作用是将网络数据流量压缩成数据报形式,提供面向事务的简单信息传送服务.与TCP协议不同,UDP协议直接利用IP协议进行UDP数据报的传输,UDP提供的是面向无连接的.不可靠的数据报投递服务.当使用UDP协议传输信息时,用户应用程序必须负责解决数据报丢失.重复.排序,差错确认等问题.由于UDP具有资源消耗小.处理速度快的优点,所以通常视频.音频等可靠性要求不高的数据传输一般会使用UDP,即便有一定的丢包率,

TCP 与 UDP 的区别

1)TCP 是传输控制协议,提供的是面向连接.可靠的字节流服务. 当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据.TCP提供超时重发. 丢弃重复数据.检验数据.流量控制等功能,保证数据能从一端传到另一端. 2)UDP 是用户数据报协议,是一个简单的面向数据报的运输层协议.UDP不提供可靠性,它只是把应用程序传给 IP层的数据报发送出去,但是并不保证它们能到达目的地.由于UDP在传输数据报之前不用在客户端和服务器之间 建立一个连接,且没有超时重发机制,故而传输速

socket、tcp、udp、http 的认识及区别

一.先来一个讲TCP.UDP和HTTP关系的 1.TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层. 在网络层有IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 在传输层中有TCP协议与UDP协议. 在应用层有FTP.HTTP.TELNET.SMTP.DNS等协议. 因此,HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议. 2.HTTP协议是建立在请求/响应模型上的. 首先由客户建立一条与服务器的TCP链接,并发送一个请求到服务器, 请求

java基础知识回顾之java Socket学习(一)--UDP协议编程

UDP传输:面向无连接的协议,不可靠,只是把应用程序传给IP层的数据报包发送出去,不保证发送出去的数据报包能到达目的地.不用再客户端和服务器端建立连接,没有超时重发等机制,传输速度快是它的优点.就像寄信,写好信放到邮箱桶里面,既不能保证信件在邮递过程中不丢失,也不能保证信件是按顺序寄到目的地的. 看java API用到java.net.DatagramSocket和java.net.DatagramPacket类: DatagramSocket:此类表示用来发送和接收数据报包的套接字(IP地址和