简单的TCP通讯程序
前言
本小节将针对已习得的关于
net
的相关知识点,编程一简单的基于net
通讯的一个小demo,主要使用nodejs的net
来创建一个服务器server对象,并使用telnet
命令与这个server对象进行通讯,而telnet
的退出命令是^]
,我们可以用其来模拟关于一个客户端的退出机制, 将一步步来递进的方式来看是如何来使用这个net的!!
1、定义全局变量,作为所有客户端共享的资源
let clientCount = 0;// 客户端连接数
let clientArray = {}; // 缓存的客户端对象
2、创建一个Server,并监听其3000端口
const net = require('node:net');
const server = net.createServer(socket => {
// ...待实现的监听方法
});
server.listen(3000);
这里我们创建了一个server对象,并对每一个连接进来的客户端进行了一个监听,socket
是作为每个连接上来的客户端的一个流的引用,可针对这个流进行读写操作!!
3、监听每一个连接
socket.setEncoding('utf-8');
console.info('\t\t有新的客户端连接进来了!');
socket.write(`欢迎您,您是第${clientCount + 1}个客户端,请写上您的名字并按回车键!\n`);
clientCount ++;
4、对每一个客户端的输入做逻辑判断
针对每一个客户端的输入,如果是第一次,则将其当作是客户端的唯一标识,如果不是第一次聊天,那么就当作是与聊天室内的其他用户一同聊天,通过对
data
时间的监听,以及额外缓存的全局变量来达到这一目的!
socket.on('data', data => { data = data.toString('utf-8').replace('\r\n', ''); if(!nickName){ if(!clientArray[data]){ // 如果客户端没有连接过-->存储这个客户端 clientArray[data] = socket; nickName = data; for(let i in clientArray){ clientArray[i].write(`\t\t${data}-->连接进房间了~\n`); } }else{ // 如果客户端已经连接过-->提示错误信息 socket.write(`${data}-->之前已经进过这个房间了,请换另外一个昵称进入房间~`); return; } }else{ for(let i in clientArray){ if(i !== nickName){ clientArray[i].write(`${nickName}对大家说:${data}\n`); } } } });
通过对缓存的每一个对象的socket,通过其write方法来实现对客户端流的写入动作!
5、监听谁谁谁退出了房间
通过
socket的close
方法,来实现对客户端退出的监听,:warning: 这里采用的是close
监听方法而不是end
监听方法,是因为当客户端提出时,不一定会调用end
,因为这个时候服务端可能还在向客户端流传输数据
socket.on('close', res => { clientCount --; for(let i in clientArray){ if(clientArray[i].destroyed){ console.info(`${i}已经退出房间了`); delete clientArray[i]; } if(clientCount > 0){ console.info(`当前还剩下${Object.keys(clientArray).join('、')}在房间里`); }else{ console.info(`目前没有人在房间里!`); } } });
通过对全局变量的访问控制,即可做到对所有连接进来的客户端进行一个统一资源的管理!
完整的例子以及运行效果
const net = require('node:net');
let clientCount = 0;// 客户端连接数
let clientArray = {}; // 缓存的客户端对象
const server = net.createServer(socket => {
socket.setEncoding('utf-8');
console.info('\t\t有新的客户端连接进来了!');
socket.write(`欢迎您,您是第${clientCount + 1}个客户端,请写上您的名字并按回车键!\n`);
clientCount ++;
socket.on('close', res => {
clientCount --;
for(let i in clientArray){
if(clientArray[i].destroyed){
console.info(`${i}已经退出房间了`);
delete clientArray[i];
}
if(clientCount > 0){
console.info(`当前还剩下${Object.keys(clientArray).join('、')}在房间里`);
}else{
console.info(`目前没有人在房间里!`);
}
}
});
let nickName;
socket.on('data', data => {
data = data.toString('utf-8').replace('\r\n', '');
if(!nickName){
if(!clientArray[data]){
// 如果客户端没有连接过-->存储这个客户端
clientArray[data] = socket;
nickName = data;
for(let i in clientArray){
clientArray[i].write(`\t\t${data}-->连接进房间了~\n`);
}
}else{
// 如果客户端已经连接过-->提示错误信息
socket.write(`${data}-->之前已经进过这个房间了,请换另外一个昵称进入房间~`);
return;
}
}else{
for(let i in clientArray){
if(i !== nickName){
clientArray[i].write(`${nickName}对大家说:${data}\n`);
}
}
}
});
});
server.listen(3000, () => {
console.info('\t\t服务开始监听了3000端口!\n');
});