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();
        }
    }

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

  • 相关阅读:
    JavaScript实现类的private、protected、public、static以及继承
    OSS网页上传和断点续传(STSToken篇)
    OSS网页上传和断点续传(OSS配置篇)
    Linq sum()时遇到NULL
    SQLSERVER事务日志已满 the transaction log for database 'xx' is full
    笔记本高分辨软件兼容问题,字体太小或模糊
    H5上传图片之canvas
    An error occurred while updating the entries. See the inner exception for details.
    无限级结构SQL查询所有的下级和所有的上级
    SQLserver 进程被死锁问题解决
  • 原文地址:https://www.cnblogs.com/itbac/p/12002248.html
Copyright © 2011-2022 走看看