欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java Socket编程实例(四)- NIO TCP实践

程序员文章站 2024-03-12 13:39:08
一、回传协议接口和tcp方式实现: 1.接口: import java.nio.channels.selectionkey; import java.io....

一、回传协议接口和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 中文参考手册》,也希望大家多多支持。