一文搞懂如何使用Node.js进行TCP网络通信
摘要: 网络是通信互联的基础,Node.js提供了net、http、dgram等模块,分别用来实现TCP、HTTP、UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录。
本文分享自华为云社区《一文搞懂如何使用Node.js进行TCP网络通信》,作者:lwq1228 。
1、构建TCP服务器
1.1、使用Node.js创建TCP服务器
为了使用Node.js创建TCP服务器,首先要调用require(‘net’)来加载net模块,然后调用net模块的createServer方法就可以轻松地创建一个TCP服务器,语法格式如下:
net.createServer([options][, connectionListener])options是一个对象参数值,有两个布尔类型的属性allowHalfOpen和pauseOnConnect。这两个属性默认都是false;
connectionListener是一个当客户端与服务端建立连接时的回调函数,这个回调函数以socket端口对象作为参数。
1.2、监听客户端的连接
使用TCP服务器的listen方法就可以开始监听客户端的连接,语法格式如下:
server.listen(port[, host][, backlog][, callback]);port:为需要监听的端口号,参数值为0的时候将随机分配一个端口号;
host:服务器地址;
backlog:连接等待队列的最大长度;
callback:回调函数。
以下代码可以创建一个TCP服务器并监听8001端口:
//引入net模块
const net = require('net');
//创建TCP服务器
const server = net.createServer(function (socket) {console.log('有新的客户端接入');
});
//设置监听端口
server.listen(8001, function () {console.log('服务正在监听中。。。')
});
运行这段代码,可以在控制台看到执行了listen方法的回调函数,如图所示:
可以使用相应的TCP客户端或者调试工具来连接这个已经创建好的TCP服务器。例如,要使用Windows的Telnet就可以用以下命令来连接:
telnet localhost 8001
连接成功后可以看到控制台打印了“有新的客户端接入”字样,表明createServer方法的回调函数已经执行,说明已经成功连接到这个创建好的TCP服务器。
server.listen()方法其实触发的是server下的listening事件,所以也可以手动监听listening事件,代码如下:
//设置监听端口
server.listen(8001);
//设置监听时的回调函数
server.on('listening', function () {console.log("服务正在监听中。。。")
});
除了listening事件外,TCP服务器还支持以下事件:
connection:当有新的链接创建时触发,回调函数的参数为socket连接对象。
close:TCP服务器关闭的时候触发,回调函数没有参数。
error:TCP服务器发生错误的时候触发,回调函数的参数为error对象。
下列代码通过net.Server类来创建一个TCP服务器,添加以上事件:
//引入net模块
const net = require('net');
//实例化一个服务器对象
const server = new net.Server();
//监听connection事件
server.on('connection', function (socket) {console.log('有新的客户端接入');
});
//设置监听端口
server.listen(8001);
//设置监听时的回调函数
server.on('listening', function () {console.log('服务正在监听中。。。');
});
//设置关闭时的回调函数
server.on('close', function () {console.log('服务已关闭');
});
//设置出错时的回调函数
server.on('error', function (err) {console.log('服务运行异常', err);
});
1.3、查看服务器监听的地址
当创建了一个TCP服务器后,可以通过server.address()方法来查看这个TCP服务器监听的地址,并返回一个JSON对象,因为这个方法返回的是TCP服务器监听的地址信息,所以应该在调用了server.listen()方法或者绑定了事件listening中的回调函数中调用该方法。这个对象的属性有:
port:TCP服务器监听的端口号;
family:说明TCP服务器监听的地址是IPv6还是IPv4;
address:TCP服务器监听的地址。
代码如下:
//引入net模块
const net = require('net');
//创建TCP服务器
const server = net.createServer(function (socket) {console.log('有新的客户端接入');
});
//设置监听端口
server.listen(8001);
//设置监听时的回调函数
server.on('listening', function () {//获取地址信息let address = server.address();//获取地址详细信息console.log("服务器监听的端口是:" + address.port);console.log("服务器监听的地址是:" + address.address);console.log("服务器监听的地址类型是:" + address.family);
});
运行结果如图:
1.4、连接服务器的客户端数量
创建一个TCP服务器后,可以通过server.getConnections()方法获取连接这个TCP服务器的客户端数量。这个方法是一个异步的方法,回调函数有两个参数:
第一个参数为error对象。
第二个参数为连接TCP服务器的客户端数量。
除了获取连接数外,也可以通过设置TCP服务器的maxConnections属性来设置这个TCP服务器的最大连接数。当连接数超过最大连接数的时候,服务器将拒绝新的连接。如下代码设置这个TCP服务器的最大连接数为3。
//引入net模块
const net = require('net');
//创建TCP服务器
const server = net.createServer(function (socket) {console.log('有新的客户端接入');//设置最大连接数量server.maxConnections = 3;server.getConnections(function (err, count) {console.log("当前连接的客户端个数为:" + count);});
});
//设置监听端口
server.listen(8001, function () {console.log("服务正在监听中。。。")
});
运行这段代码,并尝试用多个客户端连接。可以发现当客户端连接数超过3的时候,新的客户端就无法连接这个服务器了,如图所示:
1.5、获取客户端发送的数据
createServer方法的回调函数参数是一个net.Socket对象(服务器所监听的端口对象),这个对象同样也有一个address()方法,用来获取TCP服务器绑定的地址,同样也是返回一个含有port、family、address属性的对象。通过socket对象可以获取客户端发送的流数据,每次接收到数据的时候触发data事件,通过监听这个事件就可以在回调函数中获取客户端发送的数据,代码如下:
//引入net模块
const net = require('net');
//创建TCP服务器
const server = net.createServer(function (socket) {//监听data事件socket.on("data", function (data) {//打印数据console.log("接收到数据:" + data.toString());});
});
//设置监听端口
server.listen(8001, function () {console.log("服务正在监听中。。。")
});
测试结果如下:
socket对象除了有data事件外,还有connect、end、error、timeout等事件。
1.6、发送数据给客户端
调用socket.write()可以使TCP服务器发送数据,这个方法只有一个必需参数,就是需要发送的数据;第二个参数为编码格式,可选。同时,可以为这个方法设置一个回调函数。当有用户连接TCP服务器的时候,将发送数据给客户端,代码如下:
//引入net模块
const net = require('net');
//创建TCP服务器
const server = net.createServer(function (socket) {//设置消息内容const message = "Hello Client......";//发送数据socket.write(message, function () {const writeSize = socket.bytesWritten;console.log("数据发送成功,数据长度为:" + writeSize);});//监听data事件socket.on("data", function (data) {const readSize = socket.bytesRead;//打印数据console.log("接收到数据为:" + data.toString(), ";接收的数据长度为:" + readSize);});
});
//设置监听端口
server.listen(8001, function () {console.log("服务正在监听中。。。")
});
测试结果如下:
在上面这段代码中还用到了socket对象的bytesWritten和bytesRead属性,这两个属性分别代表着发送数据的字节数和接收数据的字节数。除了上面这两个属性外,socket对象还有以下属性:
socket.localPort:本地端口的地址;
socket.localAddress:本地IP地址;
socket.remotePort:进程端口地址;
socket.remoteFamily:进程IP协议族;
socket.remoteAddress:进程IP地址。
2、构建TCP客户端
Node.js在创建一个TCP客户端的时候同样使用的是net(网络)模块。
2.1、使用Node.js创建TCP客户端
为了使用Node.js创建TCP客户端,首先要调用require(‘net’)来加载net模块。创建一个TCP客户端只需要创建一个连接TCP客户端的socket对象即可:
//引入net模块
const net = require('net');
//创建TCP客户端
const client = new net.Socket();
创建一个socket对象的时候可以传入一个json对象。这个对象有以下属性:
fd:指定一个存在的文件描述符,默认值为null;
readable:是否允许在这个socket上读,默认值为false;
writeable:是否允许在这个socket上写,默认值为false;
allowHalfOpen:该属性为false时,TCP服务器接收到客户端发送的一个FIN包后,将会回发一个FIN包;该属性为true时,TCP服务器接收到客户端发送的一个FIN包后不会回发FIN包。
2.2、连接TCP服务器
创建了一个socket对象后,调用socket对象的connect()方法就可以连接一个TCP服务器,代码如下:
//引入net模块
const net = require('net');
//创建TCP客户端
const client = new net.Socket();
//设置连接的服务器
client.connect(8001, '127.0.0.1', function () {console.log("连接服务器成功");
});
连接成功如下图所示:
2.3、获取从TCP服务器发送的数据
socket对象有data、error、close、end等事件,因可以通过监听data事件来获取从TCP服务器发送的数据,代码如下:
//引入net模块
const net = require('net');
//创建TCP客户端
const client = new net.Socket();
//设置连接的服务器
client.connect(8001, '127.0.0.1', function () {console.log("连接服务器成功");
});
//监听data事件
client.on("data", function (data) {//打印数据console.log("接收到数据为:" + data.toString());
});
先启动TCP服务端,再运行上面客户端,可以发现命令行中已经输出了来自服务端的数据,说明此时已经实现了服务端和客户端之间的通信:
2.4、向TCP服务器发送数据
因为TCP客户端是一个socket对象,所以可以使用以下代码来向TCP服务器发送数据:
//引入net模块
const net = require('net');
//创建TCP客户端
const client = new net.Socket();
//设置连接的服务器
client.connect(8001, '127.0.0.1', function () {console.log("连接服务器成功");//给服务端发送数据client.write("Hello Server......");
});
//监听data事件
client.on("data", function (data) {//打印数据console.log("接收到数据为:" + data.toString());
});
//监听end事件
client.on("end", function () {console.log("客户端发送数据结束")
});
客户端控制台输出:
服务端控制台输出:
至此使用Node.js进行TCP网络通信完成,如有不对的地方欢迎指正
点击关注,第一时间了解华为云新鲜技术~
一文搞懂如何使用Node.js进行TCP网络通信相关推荐
- ES6学习——一文搞懂ES6
ES6学习--一文搞懂ES6 es6介绍 ES全称EcmaScript,是脚本语言的规范,而平时经常编写的EcmaScript的一种实现,所以ES新特性其实就是指JavaScript的新特性. 为什么 ...
- 一文搞懂 Traefik2.1 的使用
原文链接:一文搞懂 Traefik2.1 的使用 一文搞懂 Traefik2.1 的使用 核心概念 安装 ACME 中间件 灰度发布 流量复制 TCP 简单 TCP 服务 带 TLS 证书的 TCP ...
- 一文搞懂 Cocos Creator 3.0 坐标转换原理
一文搞懂 Cocos Creator 3.0 坐标转换原理 屏幕坐标 UI 触点坐标 UI 多分辨率适配方案 UI 触点获取 不同坐标之间的转换 屏幕坐标与 3D 节点世界坐标互转 3D 节点之间的坐 ...
- 都2021年了,再不学ES6你就out了 —— 一文搞懂ES6
JS干货分享 -- 一文搞懂ES6 导语:ES6是什么?用来做什么? 1. let 与 const 2. 解构赋值 3. 模板字符串 4. ES6 函数(升级后更爽) 5. Class类 6. Map ...
- 一文搞懂什么是 PostCSS
一文搞懂什么是 PostCSS 在 Web 应用开发中,CSS 代码的编写是重要的一部分.CSS 规范从最初的 CSS1 到现在的 CSS3,再到 CSS 规范的下一步版本,规范本身一直在不断的发展演 ...
- 一文搞懂 Raft 算法
一文搞懂Raft算法 正文 raft是工程上使用较为广泛的强一致性.去中心化.高可用的分布式协议.在这里强调了是在工程上,因为在学术理论界,最耀眼的还是大名鼎鼎的Paxos.但Paxos是:少数真正理 ...
- 一文搞懂JSON.stringify和JSON.parse(五)JSON.parse使用说明
一 JSON.parse特性 JSON.parse()就是将JSON字符串解析成字符串描述的JavaScript值或对象(将JSON数据解析为js原生值),例如: JSON.parse('{}'); ...
- 一文搞懂RNN(循环神经网络)
基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...
- 一文搞懂 Python 的 import 机制
一.前言 希望能够让读者一文搞懂 Python 的 import 机制 1.什么是 import 机制? 通常来讲,在一段 Python 代码中去执行引用另一个模块中的代码,就需要使用 Python ...
最新文章
- 16s及宏基因组测序公司资源--20161104
- 自动装配——@Autowired 构造器,参数,方法,属性都是从容器中获取参数组件的值||自定义组件想要使用Spring容器底层的一些组件 ApplicationContext,BeanFactory
- oracle 对象管理 01_用户及权限
- 浅析NSTimer CADisplayLink内存泄露
- wxWidgets:wxListCtrl类用法
- [Qt教程] 第24篇 数据库(四)SQL查询模型QSqlQueryModel
- python re模块 字符串匹配_re模块实现正则表达式之match()方法
- Linux下chkconfig命令介绍
- linux :Tar 命令参数详解
- 好消息:Dubbo Spring Boot要来了
- 学生a3制图标题栏尺寸手绘_机械制图基本知识点
- 【codejam_Round1B_C】Mousetrap
- Centos8关闭防火墙
- 情感驿站005:为什么大多数人永远不会真正成功?
- 使用endnote自动批量生成毕业论文参考文献
- 百度搜索引擎结果网址参数_反馈搜索结果用时(rsv_sug4)
- HTML+CSS+JavaScript实战——美团首页
- 设计模式之简单化_Mediator中介者模式_只有一个仲裁者
- jwt鉴权(react express jsonwebtoken)
- 正大新闻:炒期货巨亏7000万引股价大跌豪悦护理回购+增持
热门文章
- (4)Node.js 安装
- 必备收藏 | 超详细揭秘 Redis 持久化,建议收藏!
- HTML Form元素
- 参数幂等性校验失败_快速入手 Spring Boot 参数校验
- 为什么不能把CSS放到html中,为什么我的CSS代码不能在我的HTML文件中工作?
- java 不显示imageicon_Java ImageIcon 不能显示问题
- weka的java环境配置_Linux(ubuntu)环境下配置weka
- java 不加锁_在java中,在高并发的时候,不加锁的时候。
- springcloud灰度发布实现方案
- js如何处理后台传递过来的Map