java socket與Netty服務器通信

java socket與Netty服務器通信

本人初學java,第一次學寫技術博客:


ByteBuffer與ByteBuf

C/C++中在進行網絡通信的過程中直接面對的是字節流或是字符流。java中網絡通信的話面對的是緩衝區buffer。
ByteBuffer是來自於java.nio
ByteBuf是來自於io.netty.buffer 兩者相互轉換自然是可以的。ByteBuf的nioBuffer()方法可以得到ByteBuf對應的ByteBuffer.

使用ByteBuffer與Netty通信

在ByteBuffer 開始寫入需要傳輸數據的大小

應用的背景是通過Socket 將一個自定義類傳輸到服務器,在服務器正確解析出這個類。
在傳輸的ByteBuffer的開始四字節存儲要傳輸byte數組的長度,再將要傳輸的byte數組放入ByteBuffer中。
在接收端的相應的要在pipeline中加入兩個處理函數
LengthFieldBasedFrameDecoder()              LengthFieldPrepender()

客戶端

        if(socket == null)
            socket = new Socket(host, port);
        OutputStream out = socket.getOutputStream();
        ByteBuffer header = ByteBuffer.allocate(4);
        header.putInt(socksend.length);
        out.write(header.array());
        out.write(socksend);
        out.flush();

服務器

ch.pipeline().addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
ch.pipeline().addLast("frameEncoder", new LengthFieldPrepender(4));
ch.pipeline().addLast(new CsDecoder());
ch.pipeline().addLast(new CBgHandler());

socksend是自定義類轉換成的byte數組,
CsDecoder()是在服務器端將收到的數據轉換成自定義類

ByteBuffer 寫入數據後調用flip()函數

寫看代碼

        if(socket == null)
            socket = new Socket(host, port);
        OutputStream out = socket.getOutputStream();
        ByteBuffer header = ByteBuffer.allocate(1024);
        header.clear();
        header.put(socksend);
        header.flip();
        out.write(header.array());
        out.flush();
 ch.pipeline().addLast(new CsDecoder());
 ch.pipeline().addLast(new CBgHandler());

直接講數據寫入ByteBuffer並且不調用flip()方法的話,服務器接收到數據總是無法解析。
因爲ByteBuffer中有一個position和limit,在寫入數據的過程中position不斷增加,limit是ByteBuffer的最大容量。在讀取ByteBuffer時是從position到limit的數據。所以flip()函數的作用就是在數據寫完後將position置爲0,limit置爲寫入字節的數量,這樣ByteBuffer才能正確的du’ru。

使用ByteBuf與Netty通信

因爲ByteBuf是Netty內部實現的類,所以可以和Netty無縫銜接實現起來自然方便很多。
客戶端

        if(socket == null)
            socket = new Socket(host, port);
        OutputStream out = socket.getOutputStream();
        ByteBuf header = Unpooled.buffer(1024);
        header.writeBytes(pbdata);
        out.write(header.array());
        out.flush();

服務器

 ch.pipeline().addLast(new CsDecoder());
 ch.pipeline().addLast(new CBgHandler());
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章