摘要:网络是通信互联的基础。Node.js提供了net、http、dgram等模块,分别用于实现TCP、HTTP、UDP通信。本文主要记录使用Node.js进行TCP通信的实践。本文分享自华为云社区《一文搞懂如何使用Node.js进行TCP网络通信》,作者:lwq1228。一、搭建TCP服务器1.1.使用Node.js创建TCP服务器为了使用Node.js创建TCP服务器,首先调用require('net')加载net模块,然后调用net模块的createServer方法即可轻松创建一个TCP服务器,语法格式如下:net.createServer([options][,connectionListener])options是一个对象参数值,它有两个布尔属性allowHalfOpen和pauseOnConnect。这两个属性默认都是假的;connectionListener是客户端与服务端建立连接时的回调函数,这个回调函数以socket端口对象为参数。1.2.监听客户端连接使用TCP服务器的listen方法开始监听客户端连接。语法如下:server.listen(port[,host][,backlog][,callback]);port:要监听的端口号,当参数值为0时,会随机分配一个端口号;host:服务器地址;backlog:连接等待队列的最大长度;回调:回调函数。下面的代码可以创建一个TCP服务器并监听8001端口://引入net模块constnet=require('net');//创建一个TCP服务器constserver=net.createServer(function(socket){console.log('hasNewclientaccess');});//设置监听端口server.listen(8001,function(){console.log('服务正在监听...')});运行这段代码,可以在控制台中看到执行listen方法的回调函数,如图:可以使用对应的TCP客户端或者调试工具连接创建好的TCP服务器。例如,如果要使用WindowsTelnet,可以使用如下命令连接:telnetlocalhost8001连接成功后,可以在控制台看到“Anewclientisconnected”字样,说明回调成功createServer方法的函数已经执行完毕,说明成功连接到这个创建的TCP服务器。server.listen()方法实际上是触发server下的监听事件,所以也可以手动监听监听事件。代码如下://设置监听端口server.listen(8001);//设置监听时的回调函数server.on('listening',function(){console.log("服务正在监听...")});除了监听事件,TCP服务器还支持以下事件:connection:创建新连接时触发,callback函数的参数是socket连接对象。close:TCP服务器关闭时触发,回调函数无参数。error:当TCP服务器发生错误时触发,回调函数的参数为??error对象。下面的代码通过net.Server类创建一个TCP服务器,并添加上面的事件://引入net模块constnet=require('net');//实例化一个服务器对象constserver=newnet.Server();//监听连接事件server.on('connection',function(socket){console.log('有新客户端接入');});//设置监听端口server.listen(8001);//设置监听时的回调函数server.on('listening',function(){console.log('服务正在监听...');});//设置关闭时的回调函数server.on('close',function(){console.log('服务关闭');});//设置服务器关闭时的回调函数发生错误。on('error',function(err){console.log('服务运行异常',err);});1.3.查看服务器监听的地址。创建TCP服务器后,可以使用server.address()方法查看TCP服务器监听的地址,返回一个JSON对象,因为该方法返回的是TCP服务器监听的地址信息,所以应该在调用server.listen()方法或绑定事件监听的回调函数中调用该方法。这个对象的属性是:port:TCP服务器监听的端口号;family:表示TCP服务器监听的地址是IPv6还是IPv4;address:TCP服务器监听的地址。代码如下://引入net模块constnet=require('net');//创建一个TCP服务器constserver=net.createServer(function(socket){console.log('有一个新的客户端access');});//设置监听端口server.listen(8001);//设置监听时的回调函数server.on('listening',function(){//获取地址信息letaddress=server.address();//获取地址详情console.log("服务器监听的端口是:"+address.port);console.log("服务器监听的地址是:"+address.address);console.log("服务器监听的地址类型为:"+address.family);});运行结果如图:1.4、连接服务器的客户端数量创建TCP服务器后,可以通过server.getConnections()方法获取连接TCP服务器的客户端数量。该方法为异步方法,回调函数有两个参数:`第一个参数为错误对象。第二个参数是连接到TCP服务器的客户端数量。`除了获取连接数,还可以通过设置TCP服务器的maxConnections属性来设置TCP服务器的最大连接数。当连接数超过最大连接数时,服务器将拒绝新的连接。下面的代码设置这个TCP服务器的最大连接数为3//引入net模块constnet=require('net');//创建一个TCP服务器constserver=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对象(server的监听端口对象),这个对象还有一个address()方法,用来获取TCP服务器绑定的地址,同样返回一个对象包含端口、系列和地址属性。客户端发送的流数据可以通过socket对象获取,每次接收到数据都会触发data事件。通过监听该事件,可以在回调函数中获取到客户端发送的数据。代码如下://引入net模块constnet=require('net');//创建TCP服务器constserver=net.createServer(function(socket){//监听数据事件socket.on("data",function(data){//打印数据console.log("Receiveddata:"+data.toString());});});//设置监听端口server.listen(8001,function(){console.log("服务正在监听...")});测试结果如下:除了data事件,socket对象还有connect、end、error、timeout等事件。1.6.向客户端发送数据调用socket.write()使TCP服务器发送数据。该方法只有一个必填参数,即要发送的数据;第二个参数是编码格式,可选。同时可以为该方法设置回调函数。当用户连接到TCP服务器时,它将向客户端发送数据。代码如下://引入net模块constnet=require('net');//创建TCP服务器constserver=net.createServer(function(socket){//设置消息内容constmessage="HelloClient......";//发送数据socket.write(message,function(){constwriteSize=socket.bytesWritten;console.log("数据发送成功,数据长度为:"+writeSize);});//监听数据事件socket.on("data",function(data){constreadSize=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模块constnet=require('net');//创建一个TCP客户端constclient=newnet.Socket();创建一个socket对象可以传入一个json对象。该对象具有以下属性:fd:指定一个已存在的文件描述符,默认值为null;readable:是否允许对该socket进行读取,默认值为false;writeable:是否允许在该socket上写,默认值为false;allowHalfOpen:当该属性为false时,TCP服务器端收到客户端发送的FIN包后,会发回一个FIN包;当该属性为真时,TCP服务器将不会发回FIN数据包。2.2.连接到TCP服务器创建套接字对象后,调用套接字对象的connect()方法连接到TCP服务器。代码如下://引入net模块constnet=require('net');//创建一个TCP客户端Terminalconstclient=newnet.Socket();//设置连接的服务器client.connect(8001,'127.0.0.1',function(){console.log("连接服务器成功");});连接成功如下图:2.3.获取从TCP服务器发送的数据。socket对象有data、error、close、end等事件,因为可以通过监听data事件得到TCP服务器发送过来的数据,所以代码如下://引入net模块constnet=require('net');//创建TCP客户端constclient=newnet.Socket();//设置连接的服务器client.connect(8001,'127.0.0.1',function(){console.log("连接服务器成功");});//监听数据事件client.on("data",function(data){//打印数据console.log("接收到的数据是:"+data.toString());});先启动TCP服务器,再运行上面的客户端,可以发现命令行中已经输出了服务器端的数据,说明此时已经实现了服务器端与客户端的通信:2.4、到TCP服务端发送数据,因为TCP客户端是一个socket对象,所以可以使用如下代码向TCP服务端发送数据://引入net模块constnet=require('net');//创建一个TCPclientconstclient=newnet.Socket();//设置连接的服务器client.connect(8001,'127.0.0.1',function(){console.log("连接服务器成功");//发送数据到服务端client.write("HelloServer......");});//监听数据事件client.on("data",function(data){//打印数据console.log("接收到的数据是:"+data.toString());});//监听结束事件client.on("end",function(){console.log("Endofsendingdatabyclient")});客户端控制台输出:服务端控制台输出:至此,使用Node.js完成TCP网络通信,如有不对之处,请指正,点击关注,第一时间了解华为云的新鲜技术~
