Java Socket編程執行個體(四)- NIO TCP實踐_java

來源:互聯網
上載者:User

一、回傳協議介面和TCP方式實現:

1.介面:

import java.nio.channels.SelectionKey; import java.io.IOException;  public interface EchoProtocol {  void handleAccept(SelectionKey key) throws IOException;  void handleRead(SelectionKey key) throws IOException;  void handleWrite(SelectionKey key) throws IOException; } 

2.實現:

import java.nio.channels.*; import java.nio.ByteBuffer; import java.io.IOException;  public class TCPEchoSelectorProtocol implements EchoProtocol{   private int bufSize; // Size of I/O buffer    public EchoSelectorProtocol(int bufSize) {     this.bufSize = bufSize;   }    public void handleAccept(SelectionKey key) throws IOException {     SocketChannel clntChan = ((ServerSocketChannel) key.channel()).accept();     clntChan.configureBlocking(false); // Must be nonblocking to register     // Register the selector with new channel for read and attach byte buffer     clntChan.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufSize));        }    public void handleRead(SelectionKey key) throws IOException {     // Client socket channel has pending data     SocketChannel clntChan = (SocketChannel) key.channel();     ByteBuffer buf = (ByteBuffer) key.attachment();     long bytesRead = clntChan.read(buf);     if (bytesRead == -1) { // Did the other end close?       clntChan.close();     } else if (bytesRead > 0) {       // Indicate via key that reading/writing are both of interest now.       key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);     }   }    public void handleWrite(SelectionKey key) throws IOException {     /*      * Channel is available for writing, and key is valid (i.e., client channel      * not closed).      */     // Retrieve data read earlier     ByteBuffer buf = (ByteBuffer) key.attachment();     buf.flip(); // Prepare buffer for writing     SocketChannel clntChan = (SocketChannel) key.channel();     clntChan.write(buf);     if (!buf.hasRemaining()) { // Buffer completely written?        //Nothing left, so no longer interested in writes       key.interestOps(SelectionKey.OP_READ);     }     buf.compact(); // Make room for more data to be read in   }  } 

二、NIO TCP用戶端:

import java.net.InetSocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.SocketChannel;  public class TCPEchoClientNonblocking {    public static void main(String args[]) throws Exception {     String server = "127.0.0.1"; // Server name or IP address     // Convert input String to bytes using the default charset     byte[] argument = "0123456789abcdefghijklmnopqrstuvwxyz".getBytes();      int servPort = 5500;      // Create channel and set to nonblocking     SocketChannel clntChan = SocketChannel.open();     clntChan.configureBlocking(false);      // Initiate connection to server and repeatedly poll until complete     if (!clntChan.connect(new InetSocketAddress(server, servPort))) {       while (!clntChan.finishConnect()) {         System.out.print("."); // Do something else       }     }     ByteBuffer writeBuf = ByteBuffer.wrap(argument);     ByteBuffer readBuf = ByteBuffer.allocate(argument.length);     int totalBytesRcvd = 0; // Total bytes received so far     int bytesRcvd; // Bytes received in last read     while (totalBytesRcvd < argument.length) {       if (writeBuf.hasRemaining()) {         clntChan.write(writeBuf);       }       if ((bytesRcvd = clntChan.read(readBuf)) == -1) {         throw new SocketException("Connection closed prematurely");       }       totalBytesRcvd += bytesRcvd;       System.out.print("."); // Do something else     }      System.out.println("Received: " + // convert to String per default charset         new String(readBuf.array(), 0, totalBytesRcvd).length());     clntChan.close();   } } 

三、NIO TCP服務端:

import java.io.IOException; import java.net.InetSocketAddress; import java.nio.channels.*; import java.util.Iterator;  public class TCPServerSelector {   private static final int BUFSIZE = 256; // Buffer size (bytes)   private static final int TIMEOUT = 3000; // Wait timeout (milliseconds)      public static void main(String[] args) throws IOException {     int[] ports = {5500};     // Create a selector to multiplex listening sockets and connections     Selector selector = Selector.open();      // Create listening socket channel for each port and register selector     for (int port : ports) {       ServerSocketChannel listnChannel = ServerSocketChannel.open();       listnChannel.socket().bind(new InetSocketAddress(port));       listnChannel.configureBlocking(false); // must be nonblocking to register       // Register selector with channel. The returned key is ignored       listnChannel.register(selector, SelectionKey.OP_ACCEPT);     }      // Create a handler that will implement the protocol     TCPProtocol protocol = new TCPEchoSelectorProtocol(BUFSIZE);      while (true) { // Run forever, processing available I/O operations       // Wait for some channel to be ready (or timeout)       if (selector.select(TIMEOUT) == 0) { // returns # of ready chans         System.out.print(".");         continue;       }        // Get iterator on set of keys with I/O to process       Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();       while (keyIter.hasNext()) {         SelectionKey key = keyIter.next(); // Key is bit mask         // Server socket channel has pending connection requests?         if (key.isAcceptable()) {           System.out.println("----accept-----");           protocol.handleAccept(key);         }         // Client socket channel has pending data?         if (key.isReadable()) {           System.out.println("----read-----");           protocol.handleRead(key);         }         // Client socket channel is available for writing and          // key is valid (i.e., channel not closed)?         if (key.isValid() && key.isWritable()) {           System.out.println("----write-----");           protocol.handleWrite(key);         }         keyIter.remove(); // remove from set of selected keys       }     }   }    } 

以上就是本文的全部內容,查看更多Java的文法,大家可以關註:《Thinking in Java 中文手冊》、《JDK 1.7 參考手冊官方英文版》、《JDK 1.6 API java 中文參考手冊》、《JDK 1.5 API java 中文參考手冊》,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.