java nio编程实例_Java Socket编程实例(四)- NIO TCP实践

一、回传协议接口和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

}

}

}

}

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值