中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么用MINA、Netty、Twisted來實現消息分割

發布時間:2021-12-28 15:43:06 來源:億速云 閱讀:123 作者:小新 欄目:互聯網科技

這篇文章主要介紹了怎么用MINA、Netty、Twisted來實現消息分割,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

本文介紹一種消息分割方式,use a fixed length header that indicates the length of the body,用一個固定字節數的Header前綴來指定Body的字節數,以此來分割消息。

怎么用MINA、Netty、Twisted來實現消息分割  固定字節數的Header前綴來指定Body的字節數

上面圖中 Header 固定為 4 字節,Header 中保存的是一個 4 字節(32位)的整數,例如 12 即為 0x0000000C,這個整數用來指定 Body 的長度(字節數)。當讀完這么多字節的 Body 之后,又是下一條消息的 Header。

下面分別用MINA、Netty、Twisted來實現對這種消息的切合和解碼。

MINA

MINA 提供了 PrefixedStringCodecFactory 來對這種類型的消息進行編碼解碼,PrefixedStringCodecFactory 默認 Header 的大小是4字節,當然也可以指定成1或2。

public class TcpServer {

 public static void main(String[] args) throws IOException {
   IoAcceptor acceptor = new NioSocketAcceptor();

   // 4字節的Header指定Body的字節數,對這種消息的處理
   acceptor.getFilterChain().addLast("codec",
       new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));

   acceptor.setHandler(new TcpServerHandle());
   acceptor.bind(new InetSocketAddress(8080));
 }

}

class TcpServerHandle extends IoHandlerAdapter {

 @Override
 public void exceptionCaught(IoSession session, Throwable cause)
     throws Exception {
   cause.printStackTrace();
 }

 // 接收到新的數據
 @Override
 public void messageReceived(IoSession session, Object message)
     throws Exception {

   String msg = (String) message;
   System.out.println("messageReceived:" + msg);

 }

 @Override
 public void sessionCreated(IoSession session) throws Exception {
   System.out.println("sessionCreated");
 }

 @Override
 public void sessionClosed(IoSession session) throws Exception {
   System.out.println("sessionClosed");
 }
}

Netty

Netty 使用 LengthFieldBasedFrameDecoder 來處理這種消息。下面代碼中的new LengthFieldBasedFrameDecoder(80, 0, 4, 0, 4)中包含5個參數,分別是int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip。maxFrameLength為消息的最大長度,lengthFieldOffset為Header的位置,lengthFieldLength為Header的長度,lengthAdjustment為長度調整(默認Header中的值表示Body的長度,并不包含Header自己),initialBytesToStrip為去掉字節數(默認解碼后返回Header+Body的全部內容,這里設為4表示去掉4字節的Header,只留下Body)。

public class TcpServer {

 public static void main(String[] args) throws InterruptedException {
   EventLoopGroup bossGroup = new NioEventLoopGroup();
   EventLoopGroup workerGroup = new NioEventLoopGroup();
   try {
     ServerBootstrap b = new ServerBootstrap();
     b.group(bossGroup, workerGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(new ChannelInitializer<SocketChannel>() {
           @Override
           public void initChannel(SocketChannel ch)
               throws Exception {
             ChannelPipeline pipeline = ch.pipeline();

             // LengthFieldBasedFrameDecoder按行分割消息,取出body
             pipeline.addLast(new LengthFieldBasedFrameDecoder(80, 0, 4, 0, 4));
             // 再按UTF-8編碼轉成字符串
             pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));

             pipeline.addLast(new TcpServerHandler());
           }
         });
     ChannelFuture f = b.bind(8080).sync();
     f.channel().closeFuture().sync();
   } finally {
     workerGroup.shutdownGracefully();
     bossGroup.shutdownGracefully();
   }
 }

}

class TcpServerHandler extends ChannelInboundHandlerAdapter {

 // 接收到新的數據
 @Override
 public void channelRead(ChannelHandlerContext ctx, Object msg) {

   String message = (String) msg;
   System.out.println("channelRead:" + message);
 }

 @Override
 public void channelActive(ChannelHandlerContext ctx) {
   System.out.println("channelActive");
 }

 @Override
 public void channelInactive(ChannelHandlerContext ctx) {
   System.out.println("channelInactive");
 }

 @Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
   cause.printStackTrace();
   ctx.close();
 }
}

Twisted

在Twisted中需要繼承Int32StringReceiver,不再繼承Protocol。Int32StringReceiver表示固定32位(4字節)的Header,另外還有Int16StringReceiver、Int8StringReceiver等。而需要實現的接受數據事件的方法不再是dataReceived,也不是lineReceived,而是stringReceived。

# -*- coding:utf-8 –*-

from twisted.protocols.basic import Int32StringReceiver
from twisted.internet.protocol import Factory
from twisted.internet import reactor

class TcpServerHandle(Int32StringReceiver):

   # 新的連接建立
   def connectionMade(self):
       print 'connectionMade'

   # 連接斷開
   def connectionLost(self, reason):
       print 'connectionLost'

   # 接收到新的數據
   def stringReceived(self, data):
       print 'stringReceived:' + data

factory = Factory()
factory.protocol = TcpServerHandle
reactor.listenTCP(8080, factory)
reactor.run()

下面是Java編寫的一個客戶端測試程序:

public class TcpClient {

 public static void main(String[] args) throws IOException {

   Socket socket = null;
   DataOutputStream out = null;

   try {

     socket = new Socket("localhost", 8080);
     out = new DataOutputStream(socket.getOutputStream());

     // 請求服務器
     String data1 = "牛頓";
     byte[] outputBytes1 = data1.getBytes("UTF-8");
     out.writeInt(outputBytes1.length); // write header
     out.write(outputBytes1); // write body

     String data2 = "愛因斯坦";
     byte[] outputBytes2 = data2.getBytes("UTF-8");
     out.writeInt(outputBytes2.length); // write header
     out.write(outputBytes2); // write body

     out.flush();

   } finally {
     // 關閉連接
     out.close();
     socket.close();
   }

 }

}

MINA服務器輸出結果:

sessionCreated

messageReceived:牛頓

messageReceived:愛因斯坦

sessionClosed

Netty服務器輸出結果:

channelActive

channelRead:牛頓

channelRead:愛因斯坦

channelInactive

Twisted服務器輸出結果:

connectionMade

stringReceived:牛頓

stringReceived:愛因斯坦

connectionLost


感謝你能夠認真閱讀完這篇文章,希望小編分享的“怎么用MINA、Netty、Twisted來實現消息分割”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

瓦房店市| 阳山县| 新沂市| 新巴尔虎左旗| 吉林省| 浮山县| 铜川市| 临湘市| 黄冈市| 太原市| 广汉市| 松滋市| 石河子市| 广元市| 望江县| 沙坪坝区| 霸州市| 海城市| 连云港市| 麻栗坡县| 离岛区| 昌黎县| 三河市| 陈巴尔虎旗| 永州市| 马尔康县| 宜春市| 安福县| 永安市| 海安县| 广平县| 中卫市| 咸丰县| 七台河市| 定兴县| 丹凤县| 高唐县| 昌邑市| 寿光市| 景谷| 长泰县|