Java网络编程BIO示例,从简单到伪异步逐渐升级

    技术2024-02-23  103

    Java基础ServerSocket、Socket服务端客户端通信的示例,从简单到伪异步逐渐升级。

    文章目录

    简单示例升级示例:伪异步

    简单示例

    最加单的示例,客户端向服务端发送一个消息就结束。

    服务端代码:

    /** * 服务端 * * @Author wanglingqiang * @Date 2020/7/3 下午5:53 **/ public class Server { public static void main(String[] args) throws IOException { // 开启服务,绑定端口 ServerSocket serverSocket = new ServerSocket(6379); // 同步阻塞等待消息 Socket socket = serverSocket.accept(); // new一个数组容器 byte[] bytes = new byte[1024]; // 获得输入流 InputStream inputStream = socket.getInputStream(); // 把输入流的数据读到字节数组容器 inputStream.read(bytes); // 字节数组转成字符串 String msg = new String(bytes); // 打印 System.out.println(msg); // 关闭 inputStream.close(); socket.close(); serverSocket.close(); } }

    客户端代码:

    /** * 客户端代码 * * @Author wanglingqiang * @Date 2020/7/3 下午5:57 **/ public class Client { public static void main(String[] args) throws IOException { // 连上Server Socket socket = new Socket("127.0.0.1", 6379); // 获得输出流 OutputStream outputStream = socket.getOutputStream(); // 消息 String msg = "Hello world."; // 向输出流写字节数据 outputStream.write(msg.getBytes()); // 关闭 outputStream.close(); socket.close(); } }

    运行服务端代码,然后运行客户端代码。服务端控制台输出:

    Hello world.

    升级示例:伪异步

    示例一中accept()接收到客户端请求后,后面的读写的操作是同步进行的,在下面的示例中我们对此做升级,用一个线程池处理读写任务。

    服务端代码:

    /** * TODO * * @author wanglingqiang * @date 2020/12/9 下午2:57 */ public class Server { private static ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(); serverSocket.bind(new InetSocketAddress(6379)); System.out.println("Server started."); try { while (true) { threadPool.execute(new ServerTask(serverSocket.accept())); } } finally { serverSocket.close(); } } private static class ServerTask implements Runnable { private Socket socket; public ServerTask(Socket socket) { this.socket = socket; } @Override public void run() { try (ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream()); ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream())) { String msg = inputStream.readUTF(); System.out.println("服务端收到:" + msg); outputStream.writeUTF("success"); outputStream.flush(); } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } }

    客户端代码:

    /** * TODO * * @author wanglingqiang * @date 2020/12/9 下午3:01 */ public class Client { public static void main(String[] args) throws IOException { Socket socket = null; ObjectOutputStream outputStream = null; ObjectInputStream inputStream = null; try { socket = new Socket(); InetSocketAddress endpoint = new InetSocketAddress("127.0.0.1", 6379); socket.connect(endpoint); outputStream = new ObjectOutputStream(socket.getOutputStream()); inputStream = new ObjectInputStream(socket.getInputStream()); outputStream.writeUTF("Hello world."); outputStream.flush(); String response = inputStream.readUTF(); System.out.println(response); } catch (IOException e) { e.printStackTrace(); } finally { if (socket != null) socket.close(); if (outputStream != null) outputStream.close(); if (inputStream != null) inputStream.close(); } } 升级示例,做到了对每个客户端开启一个线程做连接后的读写操作,实现伪异步的BIO。但始终还是BIO,accept()、write()、read()方法还是同步的,想做到真正的异步要用NIO。
    Processed: 0.009, SQL: 9