java 基础之--nio 网络编程
标签:submit lis generated for channel lin oca [] ted
在传统的Java 网络编程中,对于客户端的每次连接,对于服务器来说,都要创建一个新的线程与客户端进行通讯,这种频繁的线程的创建,对于服务器来说,是一种巨大的损耗,在Java 1.4 引入Java nio 引入了 selector channel buffer 对此操作进行重新的定义:
服务端:
package com.java.baseknowledge.net;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class NioService {
//store userMap
public static Map userMap =new HashMap();
public static void main(String[] args) throws Exception {
//selector object
Selector selector =Selector.open();
//serversocketchannel object is listening client accept
ServerSocketChannel serverSocket =ServerSocketChannel.open();
//Adjusts this channel‘s blocking mode.
serverSocket.configureBlocking(false);
serverSocket.bind(new InetSocketAddress(9099));
//在selector中register channel
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
while(true) {
//block method event listening,this method is perform when event is touch;
selector.select();
//get selection-key set
Set selectedKeys = selector.selectedKeys();
selectedKeys.forEach((keys->{
//judge selectionkey mode
if(keys.isAcceptable()) {
try {
ServerSocketChannel channel = (ServerSocketChannel)keys.channel();
//obtain socketchannel
SocketChannel accept = channel.accept();
accept.configureBlocking(false);
//regist selector,listening read event
accept.register(selector, SelectionKey.OP_READ);
userMap.put(new Random().nextInt()*new Random().nextInt(), accept);
}
catch(Exception e ) {
e.printStackTrace();
}
}
else if(keys.isReadable()) {
//obtain socketchannel
try {
SocketChannel channel = (SocketChannel)keys.channel();
System.out.println(channel);
ByteBuffer by = ByteBuffer.allocate(2048);
channel.read(by);
userMap.forEach((k,v)->{
by.rewind();
if(v!=channel) {
try {
v.write(by);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
catch(Exception e) {}
}
selectedKeys.clear();
}));
}
}
}
客户端:
package com.java.baseknowledge.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* chat client
* @author Administrator
*
*/
public class JavaNioClient {
public static void main(String[] args) throws Exception {
//建立Selector
Selector selector =Selector.open();
SocketChannel socketChannel=SocketChannel.open();
//设置非阻塞
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_CONNECT);
socketChannel.connect(new InetSocketAddress("127.0.0.1", 9099));
while(true) {
selector.select();
Set setionkey =selector.selectedKeys();
for(SelectionKey kk :setionkey) {
if(kk.isConnectable()) {
//从selectionkey 获取socketChannel
SocketChannel socket=(SocketChannel)kk.channel();
//手动建立连接
if(socket.isConnectionPending()) {
socket.finishConnect();
//写数据
ByteBuffer byteB = ByteBuffer.allocate(1024);
byteB.put((System.currentTimeMillis()+"连接ok").getBytes());
byteB.flip();
socket.write(byteB);
//jdk1.5 线程池
ExecutorService exe =Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
exe.submit(new Thread() {
@Override
public void run() {
while(true) {
String msg=null;
byteB.clear();
//标准键盘输入
BufferedReader br =new BufferedReader(new InputStreamReader(System.in));
try {
msg =br.readLine();
ByteBuffer bytec = ByteBuffer.allocate(1024);
bytec.put(msg.getBytes());
bytec.flip();
socket.write(bytec);
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
socket.register(selector, SelectionKey.OP_READ);
}
else if(kk.isReadable()) {
//从selectionkey 获取socketChannel
SocketChannel socket=(SocketChannel)kk.channel();
ByteBuffer by =ByteBuffer.allocate(1024);
int a=socket.read(by);
//if(a>0) {
String receive =new String(by.array());
System.out.println(receive);
//}
}
setionkey.clear();
}
}
}
}
java 基础之--nio 网络编程
标签:submit lis generated for channel lin oca [] ted
原文地址:https://www.cnblogs.com/iscys/p/9742559.html
评论