日期:2014-05-20  浏览次数:20966 次

不关闭java socket,连续发送和接收信息,经过几轮正常发送和读取后,消息内容错误!
大家好,我目前正在开发一个网络通信框架,考虑到重复创建和关闭连接将增加额外的性能开销,所以在设计上,当客户端与服务器端建立了socket连接以后,除非一端由于异常或者主动关闭了连接外,连接将一直存活,客户端和服务器之间的数据往来只靠这一条“唯一”的管道进行,从理论上我认为这是比较良好的方式。另外为了保证数据传输的可靠性,我还在其中增加的标记头的校验,基本模型如下:

一端要想另一端发送数据,发送方必须先创建并发送数据头,数据头包含将要发送数据的长度和内容属性:如要发送一条长度为20的非文件数据,标记头为:
{%FLG:L=20,F=0%}
当接收方接收到此标记头时,将返回确认标记:{%OK%}
当发送方接收到确认标记后,发送方则将“数据本体”发送到接收方。

以上就是一个基本的发送协议。

但是在实际的开发和测试中发现,客户端向服务器利用一条socket连接发送几轮消息后,接下来就出现了数据次序错乱的问题。例如应该接收确认标记的时候却没有接收到或者是接收到的数据不是有效的确认标记,我检查过,我设计的这种模式,当不发送或不接收到当前阶段的标记时是不会继续发送下面的数据的,类似于顺序阻塞。

所以我在这里请教各位高手,我每次发送数据后一定flush的,这种问题是否和网络缓冲有关,如果实在不行也只好每次发送数据后就关闭连接,当然我不希望这样。

------解决方案--------------------
应该跟网络MTU有关吧,为了避免发送小的数据报文而浪费网络资源,你实现的是协议里的一些规定,flush以后,数据也许并不一定发送出去,而是放在缓存,够一个网络所允许的最大MTU时才发送出去的,
我感觉你没必要规定发送方先发送数据头,而是只发送指定大小的数据,接收方直接接收指定大小的数据就可以了,Socket 本身就是建立在TCP的基础上的,类似握手协议应该不用关心的
这样理解也许不对,参考下
------解决方案--------------------
这个协议是谁定义的呀?太无奈了。
------解决方案--------------------
最近我也在做这方面的东西。

你看看多接收到的东西是什么?
在什么情况下会出现?

我们这里采用的方法是,
在每个报文前加个序列号,
自己也感觉有点浪费了带宽,
但是稳定一些。