<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                為了讓你想象 Transport 如何工作,我會從一個簡單的應用程序開始,這個應用程序什么都不做,只是接受客戶端連接并發送“Hi!”字符串消息到客戶端,發送完了就斷開連接。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Case%20study%20transport%20migration.md#沒有用-netty-實現-io-和-nio)沒有用 Netty 實現 I/O 和 NIO 我們將不用 Netty 實現只用 JDK API 來實現 I/O 和 NIO。下面這個例子,是使用阻塞 IO 實現的例子: Listing 4.1 Blocking networking without Netty ~~~ public class PlainOioServer { public void serve(int port) throws IOException { final ServerSocket socket = new ServerSocket(port); //1 try { for (;;) { final Socket clientSocket = socket.accept(); //2 System.out.println("Accepted connection from " + clientSocket); new Thread(new Runnable() { //3 @Override public void run() { OutputStream out; try { out = clientSocket.getOutputStream(); out.write("Hi!\r\n".getBytes(Charset.forName("UTF-8"))); //4 out.flush(); clientSocket.close(); //5 } catch (IOException e) { e.printStackTrace(); try { clientSocket.close(); } catch (IOException ex) { // ignore on close } } } }).start(); //6 } } catch (IOException e) { e.printStackTrace(); } } } ~~~ 1.綁定服務器到指定的端口。 2.接受一個連接。 3.創建一個新的線程來處理連接。 4.將消息發送到連接的客戶端。 5.一旦消息被寫入和刷新時就 關閉連接。 6.啟動線程。 上面的方式可以工作正常,但是這種阻塞模式在大連接數的情況就會有很嚴重的問題,如客戶端連接超時,服務器響應嚴重延遲,性能無法擴展。為了解決這種情況,我們可以使用異步網絡處理所有的并發連接,但問題在于 NIO 和 OIO 的 API 是完全不同的,所以一個用OIO開發的網絡應用程序想要使用NIO重構代碼幾乎是重新開發。 下面代碼是使用 NIO 實現的例子: Listing 4.2 Asynchronous networking without Netty ~~~ public class PlainNioServer { public void serve(int port) throws IOException { ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.configureBlocking(false); ServerSocket ss = serverChannel.socket(); InetSocketAddress address = new InetSocketAddress(port); ss.bind(address); //1 Selector selector = Selector.open(); //2 serverChannel.register(selector, SelectionKey.OP_ACCEPT); //3 final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes()); for (;;) { try { selector.select(); //4 } catch (IOException ex) { ex.printStackTrace(); // handle exception break; } Set<SelectionKey> readyKeys = selector.selectedKeys(); //5 Iterator<SelectionKey> iterator = readyKeys.iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); try { if (key.isAcceptable()) { //6 ServerSocketChannel server = (ServerSocketChannel)key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_WRITE | SelectionKey.OP_READ, msg.duplicate()); //7 System.out.println( "Accepted connection from " + client); } if (key.isWritable()) { //8 SocketChannel client = (SocketChannel)key.channel(); ByteBuffer buffer = (ByteBuffer)key.attachment(); while (buffer.hasRemaining()) { if (client.write(buffer) == 0) { //9 break; } } client.close(); //10 } } catch (IOException ex) { key.cancel(); try { key.channel().close(); } catch (IOException cex) { // 在關閉時忽略 } } } } } } ~~~ 1.綁定服務器到制定端口 2.打開 selector 處理 channel 3.注冊 ServerSocket 到 ServerSocket ,并指定這是專門意接受 連接。 4.等待新的事件來處理。這將阻塞,直到一個事件是傳入。 5.從收到的所有事件中 獲取 SelectionKey 實例。 6.檢查該事件是一個新的連接準備好接受。 7.接受客戶端,并用 selector 進行注冊。 8.檢查 socket 是否準備好寫數據。 9.將數據寫入到所連接的客戶端。如果網絡飽和,連接是可寫的,那么這個循環將寫入數據,直到該緩沖區是空的。 10.關閉連接。 如你所見,即使它們實現的功能是一樣,但是代碼完全不同。下面我們將用Netty 來實現相同的功能。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Case%20study%20transport%20migration.md#采用-netty-實現-io-和-nio)采用 Netty 實現 I/O 和 NIO 下面代碼是使用Netty作為網絡框架編寫的一個阻塞 IO 例子: Listing 4.3 Blocking networking with Netty ~~~ public class NettyOioServer { public void server(int port) throws Exception { final ByteBuf buf = Unpooled.unreleasableBuffer( Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8"))); EventLoopGroup group = new OioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); //1 b.group(group) //2 .channel(OioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() {//3 @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { //4 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(buf.duplicate()).addListener(ChannelFutureListener.CLOSE);//5 } }); } }); ChannelFuture f = b.bind().sync(); //6 f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); //7 } } } ~~~ 1.創建一個 ServerBootstrap 2.使用 OioEventLoopGroup 允許阻塞模式(Old-IO) 3.指定 ChannelInitializer 將給每個接受的連接調用 4.添加的 ChannelHandler 攔截事件,并允許他們作出反應 5.寫信息到客戶端,并添加 ChannelFutureListener 當一旦消息寫入就關閉連接 6.綁定服務器來接受連接 7.釋放所有資源 下面代碼是使用 Netty NIO 實現。 ### [](https://github.com/waylau/essential-netty-in-action/blob/master/CORE%20FUNCTIONS/Case%20study%20transport%20migration.md#netty-nio-版本)Netty NIO 版本 下面是 Netty NIO 的代碼,只是改變了一行代碼,就從 OIO 傳輸 切換到了 NIO。 Listing 4.4 Asynchronous networking with Netty ~~~ public class NettyNioServer { public void server(int port) throws Exception { final ByteBuf buf = Unpooled.unreleasableBuffer( Unpooled.copiedBuffer("Hi!\r\n", Charset.forName("UTF-8"))); NioEventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); //1 b.group(new NioEventLoopGroup(), new NioEventLoopGroup()) .channel(NioServerSocketChannel.class) .localAddress(new InetSocketAddress(port)) .childHandler(new ChannelInitializer<SocketChannel>() { //3 @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ChannelInboundHandlerAdapter() { //4 @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush(buf.duplicate()) //5 .addListener(ChannelFutureListener.CLOSE); } }); } }); ChannelFuture f = b.bind().sync(); //6 f.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); //7 } } } ~~~ 1.創建一個 ServerBootstrap 2.使用 OioEventLoopGroup 允許阻塞模式(Old-IO) 3.指定 ChannelInitializer 將給每個接受的連接調用 4.添加的 ChannelInboundHandlerAdapter() 接收事件并進行處理 5.寫信息到客戶端,并添加 ChannelFutureListener 當一旦消息寫入就關閉連接 6.綁定服務器來接受連接 7.釋放所有資源 因為 Netty 使用相同的 API 來實現每個傳輸,它并不關心你使用什么來實現。Netty 通過操作接口Channel 、ChannelPipeline 和 ChannelHandler來實現。 現在你了解到了用 基于 Netty 傳輸的好處。下面就來看下傳輸的 API.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看