IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> TCP在线多用户聊天室 -> 正文阅读

[网络协议]TCP在线多用户聊天室

项目介绍

该项目是一个用TCP协议实现的多人聊天室,存在一个服务器和多个客户端,总体的思路为-开启一个服务器用于等待其他客户端的连接,有客户端连接之后我们将客户端的socket保存在一个公共的列表中,开启一个线程用于接收和转发给各个连接到服务器的用户,创建一个客户端开启两个线程一个线程用于发送给服务器数据另一个线程用于接收服务器的数据。

项目前知识

当然要是想搞明白该项目我们需要一定的TCP知识:

socket:

  1. 用于创建客户端的对象
  2. socket(String host,int port) -需要传入连接的ip 和 端口
  3. close 用于释放资源

Serversocket:

  1. 用于创建服务端对象
  2. accept() 用于监听客户端的连接,返回连接的客户端的socket对象
  3. getinputStream() 用于获取输入流,读取接受到的数据
  4. close() 用于释放资源

在使用了socket连接之后,剩下的操作就和数据流之间的操作没有什么区别。

DataInputStream 和 DataOutputStream:

  1. 功能: 实现八种基本类型数据的输入/输出。 同时,也可实现字符串的输入/输出。
  2. DataInputStream 数据的字节输入流; DataOutputStream 数据的字节输出流
  3. 特点: 八种基本类型的数据在输入/输出时,会保持类型不变。
  4. 这种流特别适合在网络上实现基本类型数据和字符串的传递。
  5. readUTF() 方法接受String值作为参数,并使用修改后的UTF-8编码将其写入当前输出流.
  6. writeWTF() 方法将经过修改的UTF-8编码的数据读取到String中并返回

项目代码

聊天室一共分为两个类:

  • Server_chat (用于创建服务器,用于接收其它客户端的消息,和分发给每个连接的客户端)
  • client_chat (用于创建用户端 ,用于连接服务器,给服务器发送消息和接收服务器返回的消息)

sever_chat.java:

public class Sever_chat {
    DataInputStream in;
    DataOutputStream out;
    Socket accept;
    List<Socket> outlist;

    public Sever_chat() {}

    public Sever_chat(Socket accept, List<Socket> outlist) throws IOException {
        this.accept = accept;
        in = new DataInputStream(accept.getInputStream());
        this.outlist = outlist;

    }

    public void service() {
        outlist.add(accept);

        new Thread(() -> {
            //            读取客户端发过来信息
            try {
//                        注意我们使用readutf接收数据 就必须用writeutf发送数据
                while (true) {
                    String s = in.readUTF();
                    System.out.println(s);
                    send_ms(s);
                }
            } catch (IOException e) {
                outlist.remove(accept);
                send_ms(accept.getInetAddress() + "离开了聊天室");
                System.out.println(accept.getInetAddress() + "离开了聊天室");
            } finally {
                try {
                    accept.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public void send_ms(String s) {
        //    将服务器接收到消息转发给连接到的每一个人

        try {
            for (Socket socket : outlist) {
                DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
                outputStream.writeUTF(s);
                outputStream.flush();
            }

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

    }


    public static void main(String[] args) throws IOException {
//        创建一个列表保存socket 连接到服务器的客户端
        List<Socket> outlist = new ArrayList<Socket>();
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true) {
//             等待客户端连接
            Socket accept = serverSocket.accept();
            Sever_chat server_file = new Sever_chat(accept, outlist);
            System.out.println(accept.getInetAddress() + "进入聊天室");
            server_file.service();
        }

    }
}

client_file.java

public class client_file {
    private String ip;
    private int port;
    private Socket socket;
    private String name;

    public client_file(String ip, int port,String name) {
        this.ip = ip;
        this.port = port;
        this.name=name;
    }

    public void client(){

        try {
            socket = new Socket(ip, port);

//            创建输出流
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            DataInputStream in = new DataInputStream(socket.getInputStream());
            Scanner scanner = new Scanner(System.in);

//            循环执行发送数据
            new Thread(()->{

                    try {
                        while (true) {
                            String s = scanner.nextLine();
                            out.writeUTF(name+":"+s);
                            out.flush();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }).start();

//            循环接收数据
            new Thread(()->{
                    try {
                        while (true) {
                            String s = in.readUTF();
                            System.out.println(s);
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }).start();

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

    }

    public static void main(String[] args) {
        new client_file("localhost",9999,"小马").client();
    }


}

如果想运行多个客户端只需要new client_file()对象就可以如我们创建一个新的类模拟创建一个新的用户:

package com.ithei.UDP_manychat;

public class feng_user {
    public static void main(String[] args) {
        new client_file("192.168.43.35",9999,"小冯").client();
    }
}

运行效果:

服务器显示:
在这里插入图片描述
客户端:小冯界面
在这里插入图片描述
客户端:小马界面
在这里插入图片描述

总结:

该项目只要理解了socket之间的通信之后,就变得非常的简单就和我们平时操作流文件没有区别,唯一写的时候有一些困惑的是,创建多个客户端去连接服务器,我将服务器接收到的客户端socket的输出流对象保存在列表中然后在将消息转发给每个客户端的时候便利每个客户端的时候每次都讲消息多次转发给同一个客户端,我试用hashcode查看他们的值是否相同显示不相同但是还是每次将消息发送给了同一个用户,后来我给列表中保存每个连接对象的socket,在给每个客户端发送消息的时候使用socket获取到输出流对象然后发送就解决了这个问题。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:34:57  更:2022-10-31 12:36:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:23:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码