用java实现内网通讯,可多开客户端链接同一个服务器

发布于:2025-05-22 ⋅ 阅读:(18) ⋅ 点赞:(0)
创建一个客户端:

package Socket;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

/*
聊天案例客户端
*/
public class Client {
    private Socket socket;

    /*
    * 构造方法用于初始化客户端
    * */
    public Client() {
        try {
            /*
            * 实例化Socket时需要指定两个信息
            * 1、服务端Ip地址,如果链接的是本机,则使用localhost即可
            * 2、服务端口,用来找到运行在服务端计算机上的服务端应用程序
            *
            * 实例化Socket的过程就是与服务端建立连接的过程,如果链接失败
            * 则会抛出异常
            * */
            System.out.println("正在链接服务端。。。");
            socket= new Socket("localhost",8088);
            System.out.println("与服务端建立链接成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /*
    * 客户端开始工作的方法
    * */
    public void start(){
        try {
            /*
            Socket提供的重要方法:
            OutputStream getOutputStream()
            * 该方法用于获取一个字节输出流,用于向服务端发送数据
            * */
            OutputStream outputStream=socket.getOutputStream();
            /*//向服务端发送一个字节数据:00000001
            outputStream.write(1);*/

            while (true){
                System.out.println("输入要发送的内容:");
            Scanner scan=new Scanner(System.in);
            String str= scan.nextLine();
                if ("exit".equalsIgnoreCase(str)){
                    break;
                }
            //用字符串表示发送的内容
            //String str="你能学会java吗?";
            //将字符串转换成字节数组
            byte[] data=str.getBytes(StandardCharsets.UTF_8);
            //先给服务端发送字节数组的字节数量,也就是要发送多少字节
            outputStream.write(data.length);
            //在将字符串转换的所有字节发送给服务端
            outputStream.write(data);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                /*
                * 当通讯完毕时,希望与对方断开链接应当调用close方法
                * 1、close方法会关闭字节输入流和字节输出流
                * 2、与对方进行四次挥手
                * */
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Client client=new Client();
        client.start();
    }
}




创建一个服务端:

package Socket;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
* 聊天程序服务端
* */
public class Server {
    /*
    *运行在服务端的ServerSocket
    * 主要工作:
    * 1、向系统申请服务端口
    * 2、监听该端口,一旦客户端通过该端口尝试链接则创建Socket与客户端建立链接
    */
    private ServerSocket serverSocket;
    private ExecutorService threadPool;

    /*
    * 构造方法
    * */
    public Server(){
        try {
            System.out.println("正在启动!");
            serverSocket=new ServerSocket(8088);
            threadPool= Executors.newFixedThreadPool(20);
            System.out.println("启动完成");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }



    public void start(){
        /*
        * accept: 接受
        *
        * ServerSocket提供的方法:accept用于接受客户端的链接
            该方法是一个阻塞方法,调用后程序"卡主",开始等待客户端的链接,一旦一个客户端
            链接,该方法会立即返回一个Socket对象用于与该客户端进行数据交互。
        * */
        try {
            while (true){
            System.out.println("等待客户端链接");
            Socket socket = serverSocket.accept();
            System.out.println("一个客户端已连接");

            //启动一个线程来处理该客户端交互
            ClientHandler handler=new ClientHandler(socket);
           /* Thread t=new Thread(handler);
            t.start();*/
            threadPool.execute(handler);
            }


        } catch(IOException e){
                e.printStackTrace();
            }

    }




    public static void main(String[] args) {
        Server server=new Server();
        server.start();
    }


    private class ClientHandler implements Runnable{
        private Socket socket;

        public ClientHandler(Socket socket){
            this.socket=socket;
        }
        public void run(){
            /*
             * Socket提供的额方法:
             * InputStream getInputStream()
             * 获取该Socket的输入流,用于读取对方发送的信息
             * */

            try {
                InputStream inputStream = socket.getInputStream();

                //读一个字节,得知客户端后续发送了多少个字节
                int len;
                /*
                * 通过网络流读取对方发送过来的一个字节数据时
                * 如果返回值为-1仍然是表达流读取到了末尾,此时只有当客户端正常断开
                * 链接(进行了四次挥手时)read读到了-1
                * */
                while ((len=inputStream.read())!=-1) {
                    //创建字节数组,存储客户端发送的字节
                    byte[] data = new byte[len];
                    //读数据
                    inputStream.read(data);
                    //将数据转换成字符串
                    String message = new String(data, StandardCharsets.UTF_8);
                    System.out.println("客户端内容:" + message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}