您的位置:首页 > 其它

# NIO 实例demo-Client

2017-08-05 21:11 148 查看

NIO 实例demo-Client

Client部分包括Client和ClientHandle两部分其中Client的时序通信图如下



Client.java

Client端启动主函数如下

package MyTestNetty.Server;
/**
* Created by User on 2017/8/4.
*/
public class Client {
public static void main(String[] args) {
int port = 8080;//指定端口号
new Thread(new TimeClientHandle1("127.0.0.1",port),"myclient").start();//启动监听线程
}
}


TimeClientHandle1.java

第二部分是ClientHandler部分代码如下:

package MyTestNetty.Server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
* Created by User on 2017/8/4.
*/
public class TimeClientHandle1 implements Runnable {
private String host;
private int port;
private Selector selector;
private SocketChannel socketChannel;
private volatile boolean stop;

public TimeClientHandle1(String host, int port) {
this.host = host == null ? "127.0.0.1" : host;
this.port = port;

try {
selector = Selector.open();//创建selector实例
socketChannel = SocketChannel.open();//创建socketChannel实例
socketChannel.configureBlocking(false);//设置为异步

} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}

@Override
public void run() {
try{
doConnect();
}catch (IOException e){
e.printStackTrace();
System.exit(1);
}

while (!stop){//轮询查询可用的key
try{
selector.select(1000);
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectionKeys.iterator();
SelectionKey key = null;
while (it.hasNext()){
key = it.next();
it.remove();
try {
hadleInput(key);
}
catch (Exception e){
if(key!=null){
key.cancel();
if(key.channel()!=null)
key.channel().close();
}
}
}
}catch (Exception e){
e.printStackTrace();
System.exit(1);
}
}

// 多路复用器关闭后,所有注册在上面的Channel和Pipe等资源都会被自动注册并关闭,所以不需要重新释放资源
if(selector!=null){
try {
selector.close();
}catch (IOException e){
e.printStackTrace();
}
}

}

private void hadleInput(SelectionKey key) throws IOException {
if(key.isValid()){
SocketChannel sc = (SocketChannel)key.channel();
if(key.isConnectable()){
if(sc.finishConnect()){
sc.register(selector,SelectionKey.OP_READ);
doWrite(sc);//向服务启发送请求(先写缓冲)
}else{
System.exit(1);
}

}
if(key.isReadable()){//读取服务端返回的数据,从还缓冲中读数据
// read data
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int readBytes = sc.read(readBuffer);
if(readBytes>0){
readBuffer.flip();
byte[] bytes=new byte[readBuffer.remaining()];
readBuffer.get(bytes);
String body = new String(bytes,"UTF-8");
System.out.println("Hello glad to see you : " + body);

this.stop=true;
}
else if(readBytes<0){
// 对端链路关闭
key.cancel();
sc.close();
}
else ; // 读到0字节,忽略
}
}
}

private void doConnect() throws IOException {
if(socketChannel.connect(new InetSocketAddress(host,port))){
socketChannel.register(selector,SelectionKey.OP_READ);
doWrite(socketChannel);
}else{
socketChannel.register(selector,SelectionKey.OP_CONNECT);
}
}
private void doWrite(SocketChannel sc) throws IOException {
byte[] req = "Clients ".getBytes();
ByteBuffer writeBuffer = ByteBuffer.allocate(req.length);
writeBuffer.put(req);
writeBuffer.flip();
sc.write(writeBuffer);
if(!writeBuffer.hasRemaining()){
System.out.println("send order to server succeed!");
}
}
}


这一部分主要是包括向服务器发送请求,以及接受来自server的信息,启动运行后可输出一下结果表示服务端启动成功(本例中我们向服务器发送的是Clients 字符串)服务器给我们反馈的是Server)



并且在服务端的控制台输出如下:



这个简单的服务器客户端NIO通信的简单demo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: