zoukankan      html  css  js  c++  java
  • 网络编程之BIO

    服务端代码:

    package com.itbac.BIO;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     * 服务器
     */
    public class BIOServer {
        public static void main(String[] args) throws IOException {
    
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器启动成功!");
            while (!serverSocket.isClosed()) {
                Socket request = serverSocket.accept(); //阻塞
                System.out.println("收到新连接:"+request.toString());
                try {
                    //获取输入流
                    InputStream inputStream = request.getInputStream(); //net 网络 + IO 输入输出流
                    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
                    String msg;
                    while (null != (msg = reader.readLine())) {  //readLine
                        if (msg.length() == 0) {
                            break;
                        }
                        System.out.println(msg);
                    }
                    System.out.println("收到数据,来自:"+request.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        request.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            serverSocket.close();
        }
    }

    客户端代码:

    package com.itbac.BIO;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.nio.charset.Charset;
    import java.util.Scanner;
    
    /**
     * 客户端
     */
    public class BIOClient {
        //字符编码
        private static Charset charset = Charset.forName("UTF-8");
    
        public static void main(String[] args) throws IOException {
            //创建套接字                     (服务端的ip,端口)
            Socket socket = new Socket("localhost", 8080);
            //获取输出流
            OutputStream out = socket.getOutputStream();
            //键盘输入
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入:");
            //获取下一行,阻塞
            String msg = scanner.nextLine();
            //写出,阻塞
            out.write(msg.getBytes(charset));
            scanner.close();
            out.close();
        }
    }

    分别启动服务器,客户端,在客户端的控制台,键盘输入:12345

    在服务端的控制台,看到以下输出:

    服务器启动成功!
    收到新连接:Socket[addr=/127.0.0.1,port=61238,localport=8080]
    12345
    收到数据,来自:Socket[addr=/127.0.0.1,port=61238,localport=8080]

    信息解释:

    服务器收到一个客户端连接,客户端地址addr ,客户端端口 port ,服务器的端口 localport  

    此时的服务器是单线程的,只能一条一条的接受数据。可以通过多线程的技术,改造一下。让代码可以支持多个客户端的消息。

    package com.itbac.BIO;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class BIOServer1 {
        public static void main(String[] args) throws IOException {
            ExecutorService executorService = Executors.newCachedThreadPool();
    
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器启动成功!");
            while (!serverSocket.isClosed()) {
                Socket request = serverSocket.accept(); //阻塞
                System.out.println("收到新连接:"+request.toString());
                executorService.submit(() -> {
                    try {
                        //获取输入流
                        InputStream inputStream = request.getInputStream(); //net 网络 + IO 输入输出流
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
                        String msg;
                        while (null != (msg = reader.readLine())) {  //readLine
                            if (msg.length() == 0) {
                                break;
                            }
                            System.out.println(msg);
                        }
                        System.out.println("收到数据,来自:"+request.toString());
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            request.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            serverSocket.close();
        }
    }

    这样就可以同时处理多个客户端的请求。

    通过启动多个客户端,可以一起想服务端发送数据了。其实浏览器也算是一个客户端,也可以和服务端交互。

    浏览器使用的HTTP协议和服务端交互,服务端只要是也用这个协议就能响应数据给浏览器。

    改造服务端代码:

    package com.itbac.BIO;
    
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    //按照 HTTP协议响应数据
    public class BIOServer2 {
        public static void main(String[] args) throws IOException {
            ExecutorService executorService = Executors.newCachedThreadPool();
    
            ServerSocket serverSocket = new ServerSocket(8080);
            System.out.println("服务器启动成功!");
            while (!serverSocket.isClosed()) {
                Socket request = serverSocket.accept(); //阻塞
                System.out.println("收到新连接:"+request.toString());
                executorService.submit(() -> {
                    try {
                        //获取输入流
                        InputStream inputStream = request.getInputStream(); //net 网络 + IO 输入输出流
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
                        String msg;
                        while (null != (msg = reader.readLine())) {  //readLine
                            if (msg.length() == 0) {
                                break;
                            }
                            System.out.println(msg);
                        }
                        //获取输出流,设置http协议报文
                        OutputStream outputStream = request.getOutputStream();
                        //协议版本 响应状态码 响应状态 换行
                        outputStream.write("HTTP/1.1 200 OK
    ".getBytes());
                        //响应内容长度 换行,响应头部和主体之间要空一行,所以又换行。
                        outputStream.write("Contenet-Length:11
    
    ".getBytes());
                        //响应主体内容
                        outputStream.write("Hello World
    ".getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        try {
                            request.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                });
            }
            serverSocket.close();
        }
    }

    这样,做到了浏览器和服务器的通信。

  • 相关阅读:
    Luckysheet如何初始化含合并单元格的数据
    Luckysheet如何一键导入本地Excel
    又发现一款纯js开源电子表格Luckysheet
    Sublime Text3 注册码(Windows/Build 3176版本)| 开发工具
    Python初学者笔记(4)-简单的通讯录
    Python初学者笔记(3):输出列表中的奇数/奇数项,字符串中的偶数项,字符串大小写转换
    安装wampserver出现“The Program can't start because MSVCR110.dll is missing from your computer. Try reinstalling the program to fix this problem”
    python初学者笔记(2):阿拉伯数字转换成中文大写
    Python初学者笔记:打印出斐波那契数列的前10项
    JavaScript弹出对话框的三种方式
  • 原文地址:https://www.cnblogs.com/itbac/p/12002248.html
Copyright © 2011-2022 走看看