使用 Java Socket 和 ServerSocket 实现客户端服务端通信的例子

版权声明:本文为博主原创文章,转载请注明出处,如有问题,欢迎指正,谢谢。 https://blog.csdn.net/qq_33404903/article/details/89421750

1.客户端和服务端 one to one

客户端


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

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        try {
            // 1.创建客户端socket,指定服务器地址和端口
            Socket socket = new Socket("localhost", 8888);

            // 2.获取输出流,向服务器端发送信息
            // 字节输出流
            OutputStream os = socket.getOutputStream();
            // 将输出流包装为打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("用户名:admin;密码:123");
            pw.flush();
            // 关闭输出流
            socket.shutdownOutput();

            // 3.获取输入流,用来读取服务器端的响应信息
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String info;
            while ((info = br.readLine()) != null) {
                System.out.println("我是客户端,服务器说:" + info);
            }

            // 4.关闭资源
            br.close();
            isr.close();
            is.close();
            pw.close();
            os.close();
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务端


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

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {
    public static void main(String[] args) {
        try {
            // 1.创建一个服务器端的Socket,即ServerSocket,指定绑定的端口,并侦听此端口
            // 建议指定 1023 之后的端口
            ServerSocket serverSocket = new ServerSocket(8888);

            // 2.调用accept方法开始监听,等待客户端的连接
            System.out.println("***服务器即将启动,等待客户端的连接");
            Socket accept = serverSocket.accept();

            // 3.获取输入流,读取客户端信息
            // 字节输入流
            InputStream is = accept.getInputStream();
            // 将字节流转换为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 为输入流添加缓冲
            BufferedReader br = new BufferedReader(isr);
            String info;
            // 循环读取客户端信息
            while ((info = br.readLine()) != null) {
                System.out.println("我是服务器,客户端说:" + info);
            }
            // 关闭输入流
            accept.shutdownInput();

            // 4.获取输出流,响应客户端的请求
            OutputStream os = accept.getOutputStream();
            // 包装为打印流
            PrintWriter pw = new PrintWriter(os);
            pw.write("欢迎您!");
            // 调用flush()方法将缓冲输入
            pw.flush();

            // 5.关闭资源
            pw.close();
            os.close();
            br.close();
            isr.close();
            is.close();
            accept.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.客户端和服务端实现 more to one

客户端代码不变,服务端改为无限循环,每当有新的客户端请求接入服务端时,就创建一个新的线程,这个线程是单个客户端专用的,具体代码如下

服务器端线程处理类


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

/**
 * 服务器端线程处理类
 */
public class ServerThread extends Thread {

    /**
     * 和本线程相关的socket
     */
    Socket socket;

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

    /**
     * 线程执行的操作,响应客户端的请求
     */
    @Override
    public void run() {
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        PrintWriter pw = null;
        OutputStream os = null;
        try {
            // 获取输入流,读取客户端的请求
            is = socket.getInputStream();
            // 将字节流转换为字符流
            isr = new InputStreamReader(is);
            // 为输入流添加缓冲
            br = new BufferedReader(isr);
            String info;
            // 循环读取客户端信息
            while ((info = br.readLine()) != null) {
                System.out.println("我是服务器,客户端说:" + info);
            }
            // 关闭输入流
            socket.shutdownInput();
            // 获取输出流,响应客户端的请求
            os = socket.getOutputStream();
            // 包装为打印流
            pw = new PrintWriter(os);
            pw.write("欢迎您!");
            // 调用flush()方法将缓冲输入
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (pw != null) {
                pw.close();
            }
            try {
                if (os != null) {
                    os.close();
                }
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (is != null) {
                    is.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服务端代码


import javax.xml.transform.Source;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 基于TCP协议的Socket通信,实现用户登录
 * 服务器端
 */
public class Server {
    public static void main(String[] args) {
        try {
            // 创建一个服务器端的Socket,即ServerSocket,指定绑定的端口,并侦听此端口
            // 建议指定 1023 之后的端口
            ServerSocket serverSocket = new ServerSocket(8888);
            Socket accept;
            System.out.println("***服务器即将启动,等待客户端的连接***");
            // 记录客户端的数量
            int count = 0;
            while (true) {
                // 调用accept方法开始监听,等待客户端的连接
                accept = serverSocket.accept();
                // 创建一个新的服务端线程
                ServerThread serverThread = new ServerThread(accept);
                // 启动线程
                serverThread.start();
                // 统计客户端的数量
                count++;
                System.out.println("客户端的数量:" + count);
                InetAddress address = accept.getInetAddress();
                System.out.println("客户端的IP:" + address.getHostAddress());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33404903/article/details/89421750