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 中文参考手册》,也希望大家多多支持。
上一篇: php图像验证码生成代码