使用Voovan进行字节流通信

Voovan是个中国人做的开源通信包,详情可以查看http://www.voovan.org/

当初选用Voovan作为系统通信框架的原因其实是因为互联网上HTTP数据传输的粘包问题,估计是客户端处理有问题,但是这种事情到最后还是怪到服务端。mina、netty的解决方式比较繁琐,倒是voovan不需要任何修改直接就解决了。

因为新设备厂商的原因,部分设备数据采用TCP Modbus方式进行数据通信,这年头做Java开发的能做字节流通信的已经很少了,只能重拾被放弃了五六年的IDE。


协议本身很简单,举个遥测例子

00000000000601040000000A

拆解开就是

  00 00         00 00      00 06       01          04         00 00           00 0A
 消息号     TCP填充     长度    设备号   操作码   起始地址   请求数据范围


Voovan默认提供了一些消息分割器,但是没有对于字节流消息的,只能自己写咯(大部分代码都在voovanTcpTest包里)

import java.nio.ByteBuffer;
import org.voovan.network.*;


/**
 *
 * @author Chen Yi 
 */
public class ModbusMesssageSplitter implements MessageSplitter {


    @Override
    public int canSplite(IoSession session, ByteBuffer byteBuffer) {
        byteBuffer.position(0);
        //modbus协议,第5、6字节为后续数据长度
        int msgNo = getUnsignedShort(byteBuffer.getShort());
        int tcpTag = getUnsignedShort(byteBuffer.getShort());
        int length = getUnsignedShort(byteBuffer.getShort());
        byteBuffer.position(0);//获取完整数据包的方式
        return length+6;
    }
    
    public static int getUnsignedShort(short data) {      //将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。
        return data & 0x0FFFF;
    }
}


创建监听端口的时候,记得不要用消息过滤器,消息分割器也换成自己写的
import java.io.IOException;

import org.voovan.network.aio.AioServerSocket;

public class AioServerSocketTest {

    public static void main(String[] args) throws IOException {
        /**
         * host: 服务发布地址。 port: 服务发布端口。 readTimeout: 读取超时时间 idleInterval:
         * 空闲事件触发时间, 单位: 秒 可以看到有两类构造函数,在构造中没有idleInterval参数的不会触发 onIdle
         * 事件,反之则会触发。
         */
        AioServerSocket serverSocket = new AioServerSocket("127.0.0.1", 2031, 0);//构造服务端类实例
        serverSocket.handler(new ServerHandlerTest());   //设置业务处理句柄
//        serverSocket.filterChain().add(new StringFilter());  //设置消息过滤器
//        serverSocket.messageSplitter(new LineMessageSplitter());
        serverSocket.messageSplitter(new ModbusMesssageSplitter());
        serverSocket.start();//启动服务类
    }

}

剩下来就是ServerHandlerTest类里的各个方法,例如onReceive(IoSession session, Object obj)方法,obj可以转成ByteBuffer进行处理,也可以转成Voovan自带的TByteBuffer。当然如果你使用过滤器,也可以将字节流转换成业务对象,那么obj就可以转为对象欢快的玩耍去咯。


其他的就是各种业务逻辑咯,大家自由发挥吧

你可能感兴趣的:(网络,JAVA)