一、回传协议接口和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 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
}
}
}
}
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!