mina、netty消息邊界問題

      網(wǎng)友投稿 733 2025-03-31

      mina、netty消息邊界問題(采用換行符)


      在TCP連接開始到結(jié)束連接,之間可能會多次傳輸數(shù)據(jù),也就是服務(wù)器和客戶端之間可能會在連接過程中互相傳輸多條消息。理想狀況是一方每發(fā)送一條消息,另一方就立即接收到一條,也就是一次write對應(yīng)一次read。但是,現(xiàn)實(shí)不總是按照劇本來走。

      MINA官方文檔節(jié)選:

      TCP guarantess delivery of all packets in the correct order. But there is no guarantee that one write operation on the sender-side will result in one read event on the receiving side. One call of IoSession.write(Object message) by the sender can result in multiple messageReceived(IoSession session, Object message) events on the receiver; and multiple calls of IoSession.write(Object message) can lead to a single messageReceived event.

      Netty官方文檔節(jié)選:

      In a stream-based transport such as TCP/IP, received data is stored into a socket receive buffer. Unfortunately, the buffer of a stream-based transport is not a queue of packets but a queue of bytes. It means, even if you sent two messages as two independent packets, an operating system will not treat them as two messages but as just a bunch of bytes. Therefore, there is no guarantee that what you read is exactly what your remote peer wrote.

      上面兩段話表達(dá)的意思相同:TCP是基于字節(jié)流的協(xié)議,它只能保證一方發(fā)送和另一方接收到的數(shù)據(jù)的字節(jié)順序一致,但是,并不能保證一方每發(fā)送一條消息,另一方就能完整的接收到一條信息。有可能發(fā)送了兩條對方將其合并成一條,也有可能發(fā)送了一條對方將其拆分成兩條。

      對此,MINA的官方文檔提供了以下幾種解決方案

      1、use fixed length messages

      使用固定長度的消息。比如每個長度4字節(jié),那么接收的時候按每條4字節(jié)拆分就可以了。

      2、use a fixed length header that indicates the length of the body

      使用固定長度的Header,Header中指定Body的長度(字節(jié)數(shù)),將信息的內(nèi)容放在Body中。例如Header中指定的Body長度是100字節(jié),那么Header之后的100字節(jié)就是Body,也就是信息的內(nèi)容,100字節(jié)的Body后面就是下一條信息的Header了。

      3、using a delimiter; for example many text-based protocols append a newline (or CR LF pair) after every message

      使用分隔符。例如許多文本內(nèi)容的協(xié)議會在每條消息后面加上換行符(CR LF,即"\r\n"),也就是一行一條消息。當(dāng)然也可以用其他特殊符號作為分隔符,例如逗號、分號等等。

      mina server

      1

      2

      3

      4

      5

      6

      7

      8

      IoAcceptor acceptor = new NioSocketAcceptor();

      // 添加一個Filter,用于接收、發(fā)送的內(nèi)容按照"\r\n"分割

      acceptor.getFilterChain().addLast( "codec" ,

      new ProtocolCodecFilter((ProtocolCodecFactory) new TextLineCodecFactory(Charset.forName( "UTF-8" ), "\r\n" , "\r\n" )));

      acceptor.setHandler((IoHandler) new TcpServerHandle2());

      acceptor.bind( new InetSocketAddress( 8080 ));

      netty server

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      mina、netty消息邊界問題

      12

      13

      14

      15

      16

      17

      18

      19

      Serverbootstrap b = new Serverbootstrap();

      b.group(bossGroup, workerGroup)

      .channel(NioServerSocketChannel. class )

      .childHandler( new ChannelInitializer() {

      @Override

      public void initChannel(SocketChannel ch)

      throws Exception {

      ChannelPipeline pipeline = ch.pipeline();

      // LineBasedFrameDecoder按行分割消息

      pipeline.addLast( new LineBasedFrameDecoder( 80 ));

      // 再按UTF-8編碼轉(zhuǎn)成字符串

      pipeline.addLast( new StringDecoder(CharsetUtil.UTF_8));

      pipeline.addLast( new TcpServerHandler2());

      }

      });

      ChannelFuture f = b.bind( 8080 ).sync();

      f.channel().closeFuture().sync();

      client

      1

      2

      3

      4

      5

      6

      7

      8

      socket = new Socket( "localhost" , 8080 );

      out = socket.getOutputStream();

      // 請求服務(wù)器

      String lines = "床前明月光\r\n疑是地上霜\r\n舉頭望明月\r\n低頭思故鄉(xiāng)\r\n" ;

      byte [] outputBytes = lines.getBytes( "UTF-8" );

      out.write(outputBytes);

      out.flush();

      但是這樣是有問題的,如果消息內(nèi)容本身就有換行符,這個肯定是不對的

      原文地址:http://www.cnblogs.com/wucao/p/3936559.html

      TCP/IP

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:如何繪制護(hù)理甘特圖(怎么繪制甘特圖醫(yī)院)
      下一篇:怎么去除不用的頁紙(怎么刪除頁面紙張)
      相關(guān)文章
      国产亚洲精品免费视频播放| 亚洲国产成人精品久久| 亚洲成av人片天堂网| 亚洲精品无码人妻无码| 久久久久亚洲国产| 亚洲美女视频网址| 激情内射亚洲一区二区三区| 亚洲色偷偷偷鲁综合| 亚洲视频人成在线播放| 亚洲国产婷婷综合在线精品| 亚洲av无码片vr一区二区三区 | 亚洲大尺码专区影院| 亚洲电影免费在线观看| 久久亚洲一区二区| 亚洲av中文无码乱人伦在线r▽| 精品国产亚洲一区二区三区| 亚洲色成人WWW永久网站| 久久久久久久尹人综合网亚洲| 亚洲爆乳精品无码一区二区三区 | 女bbbbxxxx另类亚洲| 亚洲精选在线观看| 一本色道久久88—综合亚洲精品| 亚洲成AV人片在线观看无| 国产精品亚洲一区二区三区| 亚洲免费视频网站| 午夜亚洲国产精品福利| 亚洲国产日韩在线| 亚洲自偷自偷在线制服| 久久亚洲欧洲国产综合| 国产亚洲精品成人久久网站| 亚洲精品亚洲人成在线播放| 亚洲AV无码国产丝袜在线观看| 一本天堂ⅴ无码亚洲道久久| 亚洲av乱码一区二区三区香蕉 | 亚洲看片无码在线视频| 中文字幕乱码亚洲精品一区| 亚洲精品色婷婷在线影院| 久久亚洲国产午夜精品理论片| 亚洲国产成人无码AV在线影院| 亚洲国产精品综合福利专区| 亚洲精品成人图区|