小编给大家分享一下如何使用java实现客户端与服务器,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
Java可以用来干什么
Java主要应用于:1. web开发;2. Android开发;3. 客户端开发;4. 网页开发;5. 企业级应用开发;6. Java大数据开发;7.游戏开发等。
运行效果
开启多个客户端
服务端效果:
客户端效果:
当一个客户端断开连接:
代码
因为代码中有注释,我就直接贴上来了
服务端:
package com.dayrain.server; import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.ByteBuffer;import java.nio.channels.*;import java.nio.charset.StandardCharsets;import java.util.Iterator; public class NioServer { private static final int PORT = 8081; private static final int DEFAULT_BUFFER_SIZE = 1024; private final Selector selector; private final ByteBuffer readBuffer = ByteBuffer.allocate(NioServer.DEFAULT_BUFFER_SIZE); private final ByteBuffer writeBuffer = ByteBuffer.allocate(NioServer.DEFAULT_BUFFER_SIZE); private static int count = 0; public static void main(String[] args) throws IOException { new NioServer().start(); } public NioServer() throws IOException { //创建一个服务端channel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //设置为非阻塞 serverSocketChannel.configureBlocking(false); //获取服务器socket ServerSocket socket = serverSocketChannel.socket(); //绑定ip和端口 socket.bind(new InetSocketAddress(NioServer.PORT)); //创建多路复用选择器,并保持打开状态,直到close selector = Selector.open(); //将服务器管道注册到selector上,并监听accept事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("server start on port: " + NioServer.PORT); start(); } public void start() throws IOException { //selector是阻塞的,直到至少有一个客户端连接。 while (selector.select() > 0) { //SelectionKey是channel想Selector注册的令牌,可以通过chancel取消(不是立刻取消,会放进一个cancel list里面,下一次select时才会把它彻底删除) Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); iterator.remove(); //当这个key的channel已经准备好接收套接字连接 if(selectionKey.isAcceptable()) { connectHandle(selectionKey); } //当这个key的channel已经准备好读取数据时 if(selectionKey.isReadable()) { readHandle(selectionKey); } } } } private void connectHandle(SelectionKey selectionKey) throws IOException { //注意,服务端用的是ServerSocketChannel,BIO中是ServerSocket ServerSocketChannel serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); if(socketChannel == null) { return; } socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE); System.out.println("客户端连接成功,当前总数:" + (++count)); writeBuffer.clear(); writeBuffer.put("连接成功".getBytes(StandardCharsets.UTF_8)); writeBuffer.flip(); socketChannel.write(writeBuffer); } private void readHandle(SelectionKey selectionKey){ SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); try { readBuffer.clear(); int read = socketChannel.read(readBuffer); if(read > 0) { readBuffer.flip(); String receiveData = StandardCharsets.UTF_8.decode(readBuffer).toString(); System.out.println("收到客户端消息: " + receiveData); writeBuffer.clear(); writeBuffer.put(receiveData.getBytes(StandardCharsets.UTF_8)); writeBuffer.flip(); socketChannel.write(writeBuffer); } }catch (Exception e) { try { socketChannel.close(); } catch (IOException ioException) { ioException.printStackTrace(); } System.out.println("客户端断开了连接~~"); count--; } }}
客户端
package com.dayrain.client; import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.InetAddress;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.nio.charset.StandardCharsets;import java.util.Iterator; public class NioClient { private static final int PORT = 8081; private static final int DEFAULT_BUFFER_SIZE = 1024; private final Selector selector; private final ByteBuffer readBuffer = ByteBuffer.allocate(NioClient.DEFAULT_BUFFER_SIZE); private final ByteBuffer writeBuffer = ByteBuffer.allocate(NioClient.DEFAULT_BUFFER_SIZE); public static void main(String[] args) throws IOException { NioClient nioClient = new NioClient(); //终端监听用户输入 new Thread(nioClient::terminal).start(); //这个方法是阻塞的,要放在最后 nioClient.start(); } public NioClient() throws IOException { selector = Selector.open(); SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress(InetAddress.getLocalHost(), NioClient.PORT)); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE); } public void start() throws IOException { while (selector.select() > 0) { Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); //拿到selectionKey后要删除,否则会重复处理 iterator.remove(); if(selectionKey.isReadable()) { handleRead(selectionKey); } //只要连接成功,selectionKey.isWritable()一直为true if(selectionKey.isWritable()) { handleWrite(selectionKey); } } } } private void handleWrite(SelectionKey selectionKey) throws IOException { SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); // writeBuffer有数据就直接写入,因为另开了线程监听用户读取,所以要上锁 synchronized (writeBuffer) { writeBuffer.flip(); while (writeBuffer.hasRemaining()) { socketChannel.write(writeBuffer); } writeBuffer.compact(); } } private void handleRead(SelectionKey selectionKey) throws IOException { SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); readBuffer.clear(); socketChannel.read(readBuffer); readBuffer.flip(); String res = StandardCharsets.UTF_8.decode(readBuffer).toString(); System.out.println("收到服务器发来的消息: " + res); readBuffer.clear(); } private void terminal() { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); try { String msg; while ((msg = bufferedReader.readLine()) != null) { synchronized (writeBuffer) { writeBuffer.put((msg + "\r\n").getBytes(StandardCharsets.UTF_8)); } } }catch (Exception e) { e.printStackTrace(); } } }
以上是“如何使用java实现客户端与服务器”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!