基于java NIO 的服务端与客户端代码

时间:2023-03-09 15:42:04
基于java NIO 的服务端与客户端代码

在对java NIO  selector 与 Buffer Channel  有一定的了解之后,我们进行编写java nio 实现的 客户端与服务端例子:

服务端:

public class NIOChatService {

    private static Map<String,SocketChannel> userMap =new HashMap<>();
public static void main(String[] args) throws Exception { //创建selector 对象
Selector selector =Selector.open();
//创建serverSocketChannel
ServerSocketChannel serverSocketChannel =ServerSocketChannel.open();
//设置为非阻塞
serverSocketChannel.configureBlocking(false);
//绑定端口
serverSocketChannel.bind(new InetSocketAddress(9999));
//监听客户端的连接事件,绑定在selector 上
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
//死循环
while(true) { //阻塞监听,监听是否有事件发生
selector.select();
//获取事件发生的selectionkey
Set<SelectionKey> selectedKeys = selector.selectedKeys(); for(SelectionKey key:selectedKeys) {
if(key.isAcceptable()) {
//如果是客户端的连接的话
ServerSocketChannel serverchannel=(ServerSocketChannel)key.channel();
//获取socketchannel 传输对象
SocketChannel accept = serverchannel.accept();
accept.configureBlocking(false);
accept.register(selector, SelectionKey.OP_READ);
//保存连接的用户信息
String keys ="{"+UUID.randomUUID()+"}";
userMap.put(keys, accept);
System.out.println(userMap);
} else if(key.isReadable()) {
//只要能进入到可读的,那么channel 一定是SocketChannel
SocketChannel socketChannel =(SocketChannel)key.channel(); ByteBuffer bytebuffer =ByteBuffer.allocate(1024); //读取数据到ByteBuffer socketChannel.read(bytebuffer); bytebuffer.flip();
Charset charset =Charset.forName("utf-8");
String receiveMsg=String.valueOf(charset.decode(bytebuffer).array()); for(Map.Entry<String, SocketChannel> entry:userMap.entrySet()) { ByteBuffer bys1 =ByteBuffer.allocate(1024);
bys1.put((entry.getKey()+receiveMsg).getBytes());
SocketChannel channel =entry.getValue();
bys1.flip();
channel.write(bys1); } }
//一定要进行clear 操作
selectedKeys.clear();
} ; } } }

客户端例子:

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", 9999)); while(true) {
selector.select(); Set<SelectionKey> 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();
} } } }