**BIO实现**

实现利用 BIO 模型(传统阻塞 IO 模型)实现多用户访问,要求实现服务器与 客户端代码。提示服务器端需要多线程响应客户端请求。用java实现

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class BIOServer {
    private static final int PORT = 9999; //服务器端口号

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(PORT); //创建ServerSocket

        System.out.println("等待客户端连接...");
        while (true) {
            Socket clientSocket = serverSocket.accept(); //等待客户端连接
            System.out.println("客户端连接成功:" + clientSocket.getRemoteSocketAddress());
            new Thread(new ClientHandler(clientSocket)).start(); //创建并启动新的线程处理客户端请求
        }
    }

    private static class ClientHandler implements Runnable {
        private Socket clientSocket;

        public ClientHandler(Socket clientSocket) {
            this.clientSocket = clientSocket;
        }

        @Override
        public void run() {
            try {
                InputStream inputStream = clientSocket.getInputStream(); //获取输入流
                Scanner scanner = new Scanner(inputStream);
                OutputStream outputStream = clientSocket.getOutputStream(); //获取输出流
                PrintStream printStream = new PrintStream(outputStream);

                while (scanner.hasNextLine()) { //循环读取客户端发送的数据
                    String line = scanner.nextLine();
                    System.out.println("接收到客户端消息:" + line);
                    if ("bye".equalsIgnoreCase(line)) { //如果客户端发送了"bye",则断开连接
                        System.out.println("客户端主动断开连接");
                        break;
                    } else {
                        printStream.println("【ECHO】" + line); //将接收到的数据返回给客户端
                    }
                }

                scanner.close(); //关闭输入流和输出流
                printStream.close();
                clientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
服务器端首先创建了一个ServerSocket对象,并通过调用accept()方法等待客户端连接。当客户端连接成功后,服务器端会输出连接成功的信息,并创建一个新的线程来处理客户端请求。具体来说,服务器端定义了一个内部类ClientHandler,用于处理客户端请求。在该类的run()方法中,首先获取客户端的输入流和输出流,然后通过Scanner循环读取客户端发送的数据。如果客户端发送了"bye",则断开连接;否则,服务器端将接收到的数据添加前缀"【ECHO】"后返回给客户端。最后,在处理完成后关闭输入流、输出流和Socket对象。

客户端:

java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class BIOClient {
    private static final String HOST = "localhost"; //服务器地址
    private static final int PORT = 9999; //服务器端口号

    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(HOST, PORT); //创建与服务器的连接

        InputStream inputStream = socket.getInputStream(); //获取输入流
        Scanner scanner = new Scanner(inputStream);
        OutputStream outputStream = socket.getOutputStream(); //获取输出流
        PrintStream printStream = new PrintStream(outputStream);

        Scanner consoleScanner = new Scanner(System.in);
        while (true) {
            System.out.print("请输入要发送的消息:");
            String message = consoleScanner.nextLine();

            printStream.println(message); //向服务器发送消息

            if ("bye".equalsIgnoreCase(message)) { //如果发送了"bye",则断开连接
                System.out.println("客户端主动断开连接");
                break;
            }

            if (scanner.hasNextLine()) { //读取并输出服务器响应
                String response = scanner.nextLine();
                System.out.println("收到服务器响应:" + response);
            }
        }

        consoleScanner.close(); //关闭输入流和输出流
        scanner.close();
        printStream.close();
        socket.close();
    }
}
客户端首先创建一个Socket对象,并通过它与服务器建立连接。然后,获取Socket对象的输入流和输出流,并定义一个Scanner对象用于读取用户在控制台输入的数据。在循环中,首先提示用户输入要发送的消息,并将其写入输出流中发送给服务器。如果发送了"bye",则断开连接;否则,客户端从输入流中读取服务器返回的数据,并输出到控制台。最后,在处理完成后关闭输入流、输出流和Socket对象。

总的来说,BIO模型简单易懂,但在多用户访问时会出现阻塞等待的问题,因此通常只适用于并发请求不高的场景。
    
    Runnable 是一个函数式接口,它只包含一个无参数的 run 方法,用于定义线程的执行逻辑。在实现 Runnable 接口的类中,需要将线程要执行的逻辑写在 run 方法中。当创建一个线程对象,并将该实现了 Runnable 接口的对象传递给该线程对象时,线程对象会调用实现类中的 run 方法来执行线程的任务。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值