/**
* nio 客户端
* @author Administrator
*
*/
public class NIOClient implements Runnable{
private Logger logger=LoggerFactory.getLogger("nio client");
private String host="127.0.0.1";
private int port=7001;
private SocketAddress server;
private Selector selector;
private SocketChannel sc;
private ByteBuffer buffer;
public NIOClient(String host,int port) throws IOException {
this.host=host;
this.port=port;
server=new InetSocketAddress(host,port);
selector=Selector.open();
buffer=ByteBuffer.allocate(100);
}
public NIOClient() throws IOException {
server=new InetSocketAddress(host,port);
selector=Selector.open();
buffer=ByteBuffer.allocate(100);
}
private void connect() {
try {
logger.info("建立连接.......");
if(sc!=null)sc.close();//断开重连
sc=SocketChannel.open();
sc.configureBlocking(false);
//sc.setOption(name, value);
//System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));
//sc.setOption(name, value)
//sc.setOption(StandardSocketOptions.SO_RCVBUF, 100);
//System.out.println(sc.getOption(StandardSocketOptions.SO_RCVBUF));
sc.socket().setSoTimeout(1000);
sc.socket().setReceiveBufferSize(100);
sc.connect(server);
sc.register(selector, SelectionKey.OP_CONNECT);
}catch(IOException e) {
logger.info("连接失败:"+e.toString());
}
}
@Override
public void run() {
connect();
while(true) {
try {
selector.select(1000);
} catch (IOException e) {
logger.info("提取select信号失败:"+e.toString());
}
Iterator<SelectionKey> iter=selector.selectedKeys().iterator();
while(iter.hasNext()) {
SelectionKey key=iter.next();
iter.remove();
if(key.isConnectable()) {
try {
sc.finishConnect();
//sc.configureBlocking(true);
write();
}catch(Exception e) {
logger.info("建立链接异常:"+e.toString());
connect();
}
}else if(key.isReadable()) {
try {
read();
} catch (IOException e) {
logger.info("读取数据异常:"+e.toString());
connect();
}
}
}
}
}
private void write() throws IOException {
//buffer.clear();
buffer.put("welcome\n\r".getBytes());
buffer.flip();
while(buffer.hasRemaining()){
sc.write(buffer);
}
sc.register(selector, SelectionKey.OP_READ);
}
private void read() throws IOException {
buffer.clear();
//buffer.flip();
int flag=0,counter=0;
while(true) {
flag=sc.read(buffer);
counter+=flag;
//if(buffer.remaining()==0) break;
System.out.println(flag+" "+counter+" "+buffer.remaining());
if(flag==0)break;
//buffer.clear();
}
if(counter>0) {
buffer.flip();
byte[] read=new byte[counter];
//("缓冲区: "+readCounter+" "+read.length);
buffer.get(read,0,read.length);
String expression=new String(read,"utf-8");
System.out.println(expression);
buffer.flip();
sc.write(buffer);
}
}
public static void main(String[] args) throws IOException {
NIOClient client=new NIOClient();
ExecutorService exec=Executors.newCachedThreadPool();
exec.submit(client);
}
}
socketchannel 关键参数说明:
1、socket().setSoTimeout(1000) ; read 超时时间 单位毫秒
2、socket().setReceiveBufferSize(100); read 缓冲区尺寸
3、ByteBuffer.clear(); buffer limit = capacity;position = 0;mark = -1
4、ByteBuffer.flip(); buffer limit = position;position=0;mark = -1
5、ByteBuffer.rewind() buffer position=0
读流程:
1、buffer.clear();
2、读取数据 flag=sc.read(buffer); flag==0 结束读取
3、buffer.flip(); 处理数据