nio中客户端发送一次数据,服务端通过多次readable事件才能完整读取

在C/S项目中,客户端使用普通socket发送不定长度数据给服务端,服务端通过NIO的readable事件读取。遇到问题:服务端在一次readable事件中只能读取到4380B,剩余数据在后续事件中读取,导致数据处理异常。代码分析显示,服务端可能未一次性读取完整数据包。解决方案可能涉及改进读取策略或理解NIO的readable事件触发机制。
摘要由CSDN通过智能技术生成
最近在开发一个c/s项目,主要功能是:客户端负责采集数据发送给服务端入库。

客户端与服务端交互大致过程如下:
客户端发送一次数据,服务端read一次数据并解析入库。

先描述下问题,后面会贴出较为详细的设计和代码:
调试环境:
客户端与服务端在同一台pc机(排除丢包的可能性)

问题:
该项目在调试时,会 偶然出现一个问题
如:
客户端 一次性发送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);
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值