最近在开发一个c/s项目,主要功能是:客户端负责采集数据发送给服务端入库。
客户端与服务端交互大致过程如下:
客户端发送一次数据,服务端read一次数据并解析入库。
先描述下问题,后面会贴出较为详细的设计和代码:
调试环境:
客户端与服务端在同一台pc机(排除丢包的可能性)
问题:
该项目在调试时,会 偶然出现一个问题
:
如:
客户端 一次性发送9793B的数据,服务端nio在reactor触发的一次readable事件里读取channel中的流数据,当该次readable事件的流数据读取完毕后,发现总数据量才4380B,小于客户端所发送的9793B,剩下的数据在紧接下来的一次readable事件中被读取出来。
因此,由于客户端所发送的一个数据包,服务端分为2次或多次接收,导致该数据包后续的处理均出现异常。
由于最初设计时,完全没考虑到这样的情况,也没有发现谁碰过类似的问题,导致现在改动代码会比较麻烦,还望各位英雄豪杰帮忙分析分析。
该项目的大体设计和工作过程如下:
客户端:
客户端并不使用nio,只是使用普通socket连接服务端(因为我没发现是否有区别,难道问题原因就在此?);
客户端将采集到的数据,定时发送给服务端,发送的 数据量大小是不固定的;
发送部分代码如下:
服务端:
服务端通过nio触发readable事件来 一次性读取channel中的数据、解析数据并入库。
服务端nio部分代码如下:
客户端与服务端交互大致过程如下:
客户端发送一次数据,服务端read一次数据并解析入库。
先描述下问题,后面会贴出较为详细的设计和代码:
调试环境:
客户端与服务端在同一台pc机(排除丢包的可能性)
问题:
该项目在调试时,会 偶然出现一个问题
![](/images/smiles/icon_cry.gif)
如:
客户端 一次性发送9793B的数据,服务端nio在reactor触发的一次readable事件里读取channel中的流数据,当该次readable事件的流数据读取完毕后,发现总数据量才4380B,小于客户端所发送的9793B,剩下的数据在紧接下来的一次readable事件中被读取出来。
因此,由于客户端所发送的一个数据包,服务端分为2次或多次接收,导致该数据包后续的处理均出现异常。
由于最初设计时,完全没考虑到这样的情况,也没有发现谁碰过类似的问题,导致现在改动代码会比较麻烦,还望各位英雄豪杰帮忙分析分析。
该项目的大体设计和工作过程如下:
客户端:
客户端并不使用nio,只是使用普通socket连接服务端(因为我没发现是否有区别,难道问题原因就在此?);
客户端将采集到的数据,定时发送给服务端,发送的 数据量大小是不固定的;
发送部分代码如下:
public void send2server(int command, byte[] msg) throws IOException
{
if (out != null)
{
msg = MessageFilter.addHeader(command, msg);
_log.info("发送字节数:" + msg.length);
//msg为byte[]类型
out.write(msg);
out.flush();
}
else
{
throw new IOException("输出流为空");
}
}
服务端:
服务端通过nio触发readable事件来 一次性读取channel中的数据、解析数据并入库。
服务端nio部分代码如下:
try
{
// 处理IO事件
if (key.isAcceptable())
accept(key);
else if (key.isReadable())
{
_log.debug("发现读IO");
//与此问题相关的关键代码为这句
Reader2.processKey(key); // 提交读服务线程读取客户端数据
SocketChannel sc = (SocketChannel) key.channel();
//如果为长连接
if (sc.socket().getKeepAlive())
{
key.interestOps(key.interestOps()
& ~SelectionKey.OP_READ);