网络编程2---熟悉socket:一个基于控制台输出的C/S Demo

1. 要求

建立一个基于控制台的客户端/服务器端交互信息的Demo。效果如下:
在这里插入图片描述

2. 构建项目

2.1 建立项目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 创建客户端类:Client.java

文件位置:
在这里插入图片描述

import java.io.*;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class Client {
    public static void main(String[] args) throws IOException {
        // 创建客户端的套间字
        Socket socket = new Socket();
        // 连接的超时时间,设置为3秒
        int timeOut = 3000;
        // 连接本地服务器
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), timeOut); //InetXXX表示使用IP协议

        //打印一些信息
        System.out.println("以向服务器发起连接,正在进行后续流程...");
        System.out.println("客户端:IP" + socket.getLocalAddress() + ",Port:" + socket.getLocalPort());
        System.out.println("服务器端:IP" + socket.getInetAddress() + ",Port:" + socket.getPort());

        try {
            todo(socket);
        } catch (IOException e) {
            e.printStackTrace();
            new RuntimeException("客户端异常关闭!");
        }
        // 释放资源
        socket.close();
        System.out.println("客户端已离开!");
    }


    private static void todo(Socket client) throws IOException {
        boolean flag = true; //用来标识客户是否还在,true代表用户还在,false代表已退出
        // 构建键盘输入流
        InputStream in = System.in;
        BufferedReader input = new BufferedReader(new InputStreamReader(in));

        // 构建接受服务器消息的输入流
        InputStream inputStream = client.getInputStream();
        BufferedReader socketReader = new BufferedReader(new InputStreamReader(inputStream));

        //构建输出消息到服务器的输出流
        OutputStream outputStream = client.getOutputStream();
        PrintWriter socketWriter = new PrintWriter(outputStream, true);

        while (flag) {
            System.out.println("填写信息:");
            //从键盘读取一行
            String content = input.readLine();
            //发送到服务器
            socketWriter.println(content);
            socketWriter.flush();
            //从服务器读取一行
            String echo = socketReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println("回送:" + echo);
            }
        }
        // 释放连接资源
        socketReader.close();
        socketWriter.close();
    }
}

注意:使用PrintWriter的时候设置自动清除缓存,否则数据发送不出去。或者用flush()手动清也可以。

2.2 创建客户端类:Client.java

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务器端的套间字
        ServerSocket server = new ServerSocket(2000); //服务器是本地地址,所以不用填IP
        System.out.println("服务器准备就绪~");
        System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());

        // 接受客户
        while (true) {
            // 得到客户端
            Socket client = server.accept();
            // 客户端构建异步线程
            ClientHandler clientHandler = new ClientHandler(client);
            // 启动线程
            clientHandler.start();
        }
    }

    //内部类,继承Thread,主要解决多用户问题
    public static class ClientHandler extends Thread {
        private Socket socket;          // 服务器上连接客户端的套间字
        private boolean flag = true;       // 用来标识客户是否退出

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

        @Override
        public void run() {
            super.run();
            // 打印初始信息
            System.out.println("新客户连接:IP" + socket.getInetAddress() + ",Port:" + socket.getPort());

            try {
                //构造输入流
                BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                //构造输出流
                PrintWriter socketWriter = new PrintWriter(socket.getOutputStream(), true);

                //接受已连接用户发送的信息,并回送信息
                while (flag) {
                    // 服务器接受消息
                    String content = socketReader.readLine();
                    //服务器回写消息
                    if ("bye".equalsIgnoreCase(content)) {
                        flag = false;
                        socketWriter.println("bye");
                    } else {
                        System.out.println(content);
                        socketWriter.println("" + content.length());
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                new RuntimeException("服务器端异常");
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43546676/article/details/105584652