Skip to content

Instantly share code, notes, and snippets.

@qeesung
Created May 11, 2019 04:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qeesung/2cb8d5b35582a08dc419bcc6af41de83 to your computer and use it in GitHub Desktop.
Save qeesung/2cb8d5b35582a08dc419bcc6af41de83 to your computer and use it in GitHub Desktop.
Java Nio client
public class NioClient {
// 创建一个套接字通道,注意这里必须使用无参形式
private Selector selector = null;
static Charset charset = Charset.forName("UTF-8");
private volatile boolean stop = false;
public ArrayBlockingQueue<String> arrayQueue = new ArrayBlockingQueue<String>(8);
public void init() throws IOException{
selector = Selector.open();
SocketChannel channel = SocketChannel.open();
// 设置为非阻塞模式,这个方法必须在实际连接之前调用(所以open的时候不能提供服务器地址,否则会自动连接)
channel.configureBlocking(false);
if(channel.connect(new InetSocketAddress("127.0.0.1",7777))){
channel.register(selector, SelectionKey.OP_READ);
//发送消息
doWrite(channel, "66666666");
}else {
channel.register(selector, SelectionKey.OP_CONNECT);
}
//启动一个接受服务器反馈的线程
// new Thread(new ReceiverInfo()).start();
while (!stop){
selector.select(1000);
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
SelectionKey key = null;
while (it.hasNext()){
key = it.next();
it.remove();
SocketChannel sc = (SocketChannel) key.channel();
// OP_CONNECT 两种情况,链接成功或失败这个方法都会返回true
if (key.isConnectable()){
// 由于非阻塞模式,connect只管发起连接请求,finishConnect()方法会阻塞到链接结束并返回是否成功
// 另外还有一个isConnectionPending()返回的是是否处于正在连接状态(还在三次握手中)
if (channel.finishConnect()) {
/* System.out.println("准备发送数据");
// 链接成功了可以做一些自己的处理
channel.write(charset.encode("I am Coming"));
// 处理完后必须吧OP_CONNECT关注去掉,改为关注OP_READ
key.interestOps(SelectionKey.OP_READ);*/
sc.register(selector,SelectionKey.OP_READ);
// new Thread(new DoWrite(channel)).start();
doWrite(channel, "66666666");
}else {
//链接失败,进程推出或直接抛出IOException
System.exit(1);
}
} if(key.isReadable()){
//读取服务端的响应
ByteBuffer buffer = ByteBuffer.allocate(1024);
int readBytes = sc.read(buffer);
String content = "";
if (readBytes>0){
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
content+=new String(bytes);
stop=true;
}else if(readBytes<0) {
//对端链路关闭
key.channel();
sc.close();
}
System.out.println(content);
key.interestOps(SelectionKey.OP_READ);
}
}
}
}
private void doWrite(SocketChannel sc,String data) throws IOException{
byte[] req =data.getBytes();
ByteBuffer byteBuffer = ByteBuffer.allocate(req.length);
byteBuffer.put(req);
byteBuffer.flip();
sc.write(byteBuffer);
if(!byteBuffer.hasRemaining()){
System.out.println("Send 2 client successed");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment