如何创建一个TCP多人聊天室?

一、什么是TCP?

TCP(Transmission Control Protocol)是一种可靠的 面向连接的协议 ,可以保证数据在传输过程中不会丢失、重复或乱序。 利用TCP实现简单聊天程序,需要客户端和服务器端之间建立TCP连接,并通过套接字(Socket)进行通信。

二、代码实现:

以下分为客户端和服务器端两个模块,我对这两个模块的每一行代码做了详细解释,如下:

(1)服务器端:

//(1)引入 net 模块: net模块是 Node.js 的一个内置模块,用于创建基于 TCP 的服务器和客户端。 
const net = require('net');
//(2)创建一个 TCP 服务器。此时,服务器还没有开始监听任何端口
const server = net.createServer();
//(3)声明一个数组users用于存储所有已连接的用户的 socket 对象。每当有新的连接进入时,这个数组就会更新。
var users = [];
//(4)当有新的连接进入时,服务器会触发 connection 事件。此时,我们为每一个新的连接创建一个新的 socket 对象。
server.on('connection', (socket) => {
//(5)遍历users来找到每个客户端的socket对象发出消息 一一> 当一个新的连接进入时,我们向所有已连接的用户发送欢迎消息,告诉他们有新的用户(通过其远程端口号 socket.remotePort 标识)加入了聊天室。
    users.forEach(user => { 
//(6)socket.remotePort是 socket 对象的一个内置属性,当使用网络相关的 API(如 net 或 http 模块)时,该对象通常表示一个网络连接。
// socket.remotePort 属性表示远程连接的端口号。当你有一个服务器监听多个连接时,这个属性可以帮助你确定是哪个端口上的客户端连接触发了某个事件或行为。
        user.write('欢迎' + socket.remotePort + '进入聊天室');
    });
//(7)当从客户端接收到数据时,socket 会触发 data 事件。此时,我们可以处理接收到的数据。
    socket.on('data',(data)=>{
//(8)当从某个 socket 接收到数据时,我们遍历 users 数组并向除了发送该数据的 socket 之外的所有 socket 发送广播。这样,所有的客户端都可以看到其他客户端发送的消息,实现了一个简单的聊天室功能。
        users.forEach(user=>{  //转发
            // 判断是不是自己(本身的客户端) 是就不需要进行信息转发
            if(user!=socket){ //将要发出的消息加工,标明是谁说的
                user.write(socket.remotePort+'说'+data.toString());
            }
        });
    });
//(9)Socket 错误事件监听,捕获错误在控制台上打印出错误的消息
    socket.on('error',(err)=>{
        console.log(err.message);
    });
//(10)Socket 关闭事件监听,触发 close 事件。这个事件监听器在控制台上打印出退出聊天室的客户端的远程端口号,这样我们就可以知道哪个客户端已经断开连接
    socket.on('close',()=>{
        console.log(socket.remotePort+'退出聊天室');
    });
//(11)把socket对象保存到users里面去
    users.push(socket);
});

//(12)服务器错误事件监听,这个事件监听器确保任何服务器启动时的错误都会被捕获并打印出来。
server.on('error', (err) => {
    console.log(err.message);
});
//(13)服务器关闭事件监听,这样我们就可以知道服务器何时被关闭。
server.on('close', () => {
    console.log('聊天室已关闭');
});
//(14)启动服务器并监听端口
server.listen(3000, '127.0.0.1', () => {
    console.log('服务器已启动,监听127.0.0.1:3000');
});

(2)客户端:

客户端程序的主要功能是连接到服务器,将用户的键盘输入发送到服务器,接收并显示来自服务器的响应,同时处理连接过程中的错误和关闭事件
//(1)使用Node.js 内置的 net 模块来与服务器进行网络通信
const net=require('net');
//(2)使用 net.createConnection() 方法来创建一个到指定主机和端口的 TCP 连接。host 参数是 '127.0.0.1',即本地机器的地址,port 参数是 3000,即之前服务器监听的端口
const client=net.createConnection({
    host:'127.0.0.1',
    port:3000
});
//(3)当客户端成功连接到服务器时,会触发 'connect' 事件
client.on('connect',()=>{
//(4)监听连接事件。给 process.stdin 流注册一个事件监听器。,process 是一个全局对象,它提供了有关当前 Node.js 进程的信息和控制能力。process.stdin 是这个对象的一个属性,它表示进程的标准输入流。这是一个可读流(Readable Stream),通常与终端(命令行界面)或进程的其他输入源相关联。
//监听来自标准输入(通常是键盘输入)的 'data' 事件。当用户在命令行中输入数据时,这些数据会被捕获,并通过 client.write() 方法发送到服务器。这里,data.toString() 是为了确保数据以字符串的形式发送
    // 链接成功,准备聊天
    process.stdin.on('data',(data)=>{
        client.write(data.toString());
    })
});
//(5)监听来自服务器的数据。当客户端收到来自服务器的数据时,会触发 'data' 事件。事件处理函数会捕获这些数据,并通过 console.log() 方法将它们打印到控制台上。这里同样使用了 data.toString() 来确保数据以字符串形式被正确处理
client.on('data',(data)=>{
    //将接收到服务器端发过来的消息后通过data.toString()原样输出
    console.log(data.toString());
});
//(6)监听错误事件。如果在与服务器通信过程中发生任何错误 'error' 事件将被触发。事件处理函数会打印出错误消息,帮助我们了解发生了什么错误。
client.on('error',(err)=>{
    console.log(err.message);
});
//(7)监听关闭事件。当客户端与服务器的连接关闭时,会触发 'close' 事件。事件处理函数简单地打印出一条消息,告知用户已经退出了聊天室
client.on('close',()=>{
    console.log('已退出聊天室');
});

三、运行结果如图所示:

打开一个服务器端、两个客户端

两个客户端如图所示:

 当一个客户端退出时,服务器端如图所示:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/518043.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【数据分析面试】10. 计算平均通勤时间(SQL:timestampdiff() 和datediff()区别)

题目 假设你在Uber工作。rides表包含了关于Uber用户在美国各地的行程信息。 编写一个查询,以获取纽约(NY)每位通勤者的平均通勤时间(以分钟为单位),以及纽约所有通勤者的平均通勤时间(以分钟为…

谈谈 MySQL 的锁

前言 在 MySQL 中,锁这个定义其实还是蛮重要的。经过我这几天的学习,我感觉锁是一个可以说难又可以说不难的知识点。难就难在锁可以与事务、多线程、并发结合在一起,这就很难了。但是,假如锁没有结合这些知识点,就单单…

产品推荐 | 中科亿海微推出亿迅®A8000金融FPGA加速卡

01、产品概述 亿迅A8000金融加速卡,是中科亿海微联合金融证券领域的战略合作伙伴北京睿智融科,将可编程逻辑芯片与金融行业深度结合,通过可编程逻辑芯片对交易行情加速解码,实现低至纳秒级的解码引擎,端到端的处理时延…

【Arthas案例】某应用依赖两个GAV-classifier不同的snakeyaml.jar,引起NoSuchMethodError

多个不同的GAV-classifier依赖冲突,引起NoSuchMethodError Maven依赖的三坐标体系GAV(G-groupId,A-artifactId,V-version) classifier通常用于区分从同一POM构建的具有不同内容的构件物(artifact)。它是可选的&#xf…

每日一题:矩阵置零

给定一个 m x n 的矩阵,如果一个元素为 0 ,则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1: 输入:matrix [[1,1,1],[1,0,1],[1,1,1]] 输出:[[1,0,1],[0,0,0],[1,0,1]]使用两个标记变量。 class Sol…

Pygame基础10-物理模拟

PyMunk PyMunk是一个模拟物理的库。 注意,PyMunk只是进行物理模拟,不包含可视化的功能。如果需要可视化,可使用pygame等库。 可用pip安装pymunk pip install pymunk pymunk中的概念: space: 物理空间。 包含gravity 模…

网络抓包专题

导航目录 HTTP 原理HTTPS 原理TLS 原理网络抓包原理一. 什么是抓包?二. 抓包的原理对HTTP请求进行抓包对HTTPS请求进行抓包 三. Android设备抓包问题Android6.0 及以下系统Android7.0 及以上系统方式一:方式二 HTTP 原理 HTTP 详解 点击跳转 HTTPS 原理…

MPEG-1 详解

MPEG-1 详解 MPEG-1 详解特点MPEG-1 中的运动补偿与 B 帧的引入MPEG-1 vs H.261MPEG-1 视频数据流的结构MPEG-1 视频压缩模式MPEG-1 视频解码框图MPEG-1 音频编码模式MPEG-1 audio layer 1MPEG-1 audio layer 2MPEG-1 audio layer 3 MPEG-1 音频编码框图MPEG-1 音频解码框图参考…

基于matlab解决鸡兔同笼问题

一、什么是鸡兔同笼? 鸡兔同笼问题是一种经典的数学问题,最早出自于《孙子算经》,详细成书时间不详,但可以确定的是,它不早于汉代,不晚于南北朝时期[6]。这个问题在中国数学史上具有重要的意义&#xff0c…

WEB漏洞挖掘详细教程--用户输入合规性(sql注入测试)

前置教程:WEB漏洞挖掘(SRC)详细教程--信息收集篇-CSDN博客 WEB漏洞挖掘(SRC)详细教程--身份认证与业务一致性-CSDN博客 WEB漏洞挖掘(SRC)详细教程--业务数据篡改-CSDN博客 2.4 用户输入合规性…

RabbitMQ基于Java实现消息应答

RabbitMQ 概念 RabbitMQ是一个消息中间件:它接受并转发消息。你可以把它当做一个快递站点,当你要发送一个包裹时,你把你的包裹放到快递站,快递员最终会把你的快递送到收件人那里,按照这种逻辑RabbitMQ是一个快递站, 一个快递员帮你传递快件…

Golang Gin框架

1、这篇文章我们简要讨论一些Gin框架 主要是给大家一个基本概念 1、Gin主要是分为路由和中间件部分。 Gin底层使用的是net/http的逻辑,net/http主要是说,当来一个网络请求时,go func开启另一个协程去处理后续(类似epoll)。 然后主协程持续…

备战蓝桥杯---递归与DFS刷题2

1. 数据范围允许直接暴力把所有组合都写一遍,我们用Pair来存,在sort中分式比较只要把自己的分子与对方的分母乘比较即可,下面介绍一下st树的写法,具体原理就不说了,它是先[0/1,1/1]然后取分子分母的平均化成两个区间&a…

【C++】学习多态原理

目录 一、虚函数表二、多态原理三、关于动态绑定与静态绑定 一、虚函数表 先来看一段代码&#xff1a;sizeof(Base)是多少&#xff1f; class Base { public:virtual void Func1(){cout << "Func1()" << endl;} private:int _b 1; };int main() {cout…

【Linux】make 工具和 Makefile 文件的引入

前面提到了 gcc 编译器&#xff0c;那么使用 gcc 编译器肯定就会接触到 Makefile 。当源码文件比较多的时候就不适合通过直接输入 gcc 命令来编译&#xff0c;这时候就需要一个自动化的编译工具 make 。 举例&#xff1a;通过键盘输入两个整形数字&#xff0c;然后计算他们的和…

elasticSearch原理浅尝

终于等到你 马上就要放弃 开个玩笑 &#xff0c;进入正题 on fire 基础的咱不说了&#xff0c;一搜一麻袋 读 全文检索&#xff1a; 协调节点广播查询请求到相关分片 并 将其响应 整合 全局排序 返回结果集合 带路由&#xff1a;具体文档 shard hash(document_id) % (…

国外服务器托管需要了解哪些信息

国外服务器托管服务提供了一种在国外租用并管理服务器的方式&#xff0c;适用于需要特定地域服务或对本地法规有特殊要求的企业和个人。那么想要进行国外服务器托管需要了解哪些信息呢?Rak部落小编为您整理发布国外服务器托管相关内容。 以下是一些关于国外服务器托管服务的详…

YoloV8改进策略:BackBone改进|ELA

文章目录 摘要1、引言2、相关工作3、方法3.1、重新审视坐标注意力3.1.1、坐标注意力3.1.2、坐标注意力的不足 3.2、高效局部注意力3.3、多个ELA版本设置3.4、可视化3.5、实现 4、实验4.1、实验细节4.2、ImageNet上的图像分类4.3、目标检测4.4、语义分割 5、结论 摘要 https://…

如何搭建自己的百度网盘目录树搜索系统

许多做虚拟资源的小伙伴都有好几个百度网盘账号&#xff0c;大部分也都是扩容盘&#xff0c;但是扩容盘不能搜索&#xff0c;这个就很难受&#xff0c;不能让用户搜索自己的资源&#xff0c;这无意是是对成交概率是致命的&#xff0c;几百万条的数据&#xff0c;不能让用户一个…

【Java】jdk1.8 Java代理模式,Jdk动态代理讲解(非常详细,附带class文件)

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 一、什么是代理模式 想要学代理模式&#xff0c;我们就要先弄清一个概念“什么是代理”&#xff1f; 在我们的现实生活中&#xff0c;你或许不少听过关于代理的名词&#xff0c;如&#xff1a;代理商。那什么又叫做代理…