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

复制代码
创建一个客户端:

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

        }
    }
}
相关推荐
551只玄猫1 小时前
【数学建模 matlab 实验报告12】聚类分析和判别分析
开发语言·数学建模·matlab·课程设计·聚类·实验报告
小陈工3 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
H Journey3 小时前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake
一定要AK7 小时前
Spring 入门核心笔记
java·笔记·spring
A__tao7 小时前
Elasticsearch Mapping 一键生成 Java 实体类(支持嵌套 + 自动过滤注释)
java·python·elasticsearch
KevinCyao7 小时前
java视频短信接口怎么调用?SpringBoot集成视频短信及回调处理Demo
java·spring boot·音视频
lly2024067 小时前
C 标准库 - `<stdio.h>`
开发语言
沫璃染墨7 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
jwn9997 小时前
Laravel6.x核心特性全解析
开发语言·php·laravel
迷藏4947 小时前
**发散创新:基于Rust实现的开源合规权限管理框架设计与实践**在现代软件架构中,**权限控制(RBAC)** 已成为保障
java·开发语言·python·rust·开源