Node.js对TCP/Socket的实现之net模块TCP客户端详解

 2015年08月10日    3410     声明


使用Node.js的net模块可以很容易的构建一个TCP客户端,TCP客户端可以用来连接至TCP服务端。建立TCP连接后,两者之间会基于流进行数据交互,一个是接收数据的可读流,一个是发送数据的可写流。创建TCP客户端可以使用构造函数net.Socket()或使用net. createConnection()net. connect())方法。

  1. 连接TCP服务端
  2. 和服务端交互数据
  3. Socket流的暂停与关闭
  4. Socket客户端一些设置和方法
  5. Socket类中的属性


1. 连接TCP服务端

连接TCP服务端要创建一个客户端对象,这个对象是是一个UNIX Socket,即:net.Socket实例。它是了一个双向的流接口,创建对象服务器端的connection事件会被触发。

创建一个TCP客户端可以使用createConnection()方法或其别名方法connect(),也可以使用构造函数new net.Socket()。连接成功后'connect'事件会被触发。

//connect连接服务器通过监听函数给服务器发送数据
var client = net.connect({port: 2345}, function() {
    console.log('已连接到服务器');
    client.write('itbilu.com!\r\n');
});
//通过监听connection事件,连接后给服务器发送数据
var client = net.connect({port: 2345});
client.on('connection', function() {
    console.log('已连接到服务器');
    client.write('itbilu.com!\r\n');
});


2. 和服务端交互数据

与TCP服务端建立连接后就可以向服务端发送数据,或接收来自服务器的数据。接收到服务器端的数据数据后后触发data事件,可以通监听这个事件接收数据。向服务器发送数据可以使用write()方法。数据传输前可以通过setEncoding()方法设置流的编码格式。

  • socket.write(data, [encoding], [callback]):在UNIX Socket套接字上发送数据时,如果第二参数用于设置发送数据的编码方式,默认为UTF8编码。

    如果所有数据被成功刷新到缓冲区,则返回true。如果所有或部分数据在用户内存里还处于队列中,则返回false。当缓冲区再次被释放时,'drain'事件会被触发。

    当数据最终被完整写入时,可选参数callback会被执行。

  • socket.setEncoding([encoding]):设置Socket流的编码格式


3. Socket流的暂停与关闭

关闭与终端的的连接使用end()方法,end()方法在关闭连接前也可以向终端发送数据。对于发生错误的连接,可以调用destroy()方法,关闭已没有 I/O 活动的TCP连接。

  • socket.end(data, [encoding]):半关闭Socket套接字。例如:当发送一个FIN包时,可能服务器仍在发送数据。

    如果传入data参, 等同于调用 socket.write(data, encoding)然后调用socket.end().

  • socket.destroy():销毁已没有I/O活动的TCP连接


Socket客户端是一个可读写的流,这意味着你可以对它进行暂停和恢复。

  • socket.pause():暂停读取数据,暂停后'data'事件不会再触发
  • socket.resume():恢复pause()方法暂停的流


4. Socket客户端一些设置和方法

除了前面介绍的设置编码的setEncoding()方法外,还有其它一些设置方法,如:设置超时的setTimeout()方法。

  • socket.setTimeout(timeout[, callback]):套接字超过timeout毫秒闲置状态,则将套接字设为超时。默认net.Socket不存在超时。

    当一个闲置超时被触发时,会触发一个'timeout'事件,但是连接将不会被断开。用户必须手动end()destroy()断开这个套接字。可选参数callback会被添加成为'timeout'事件的一次性监听器。

  • socket.setNoDelay([noDelay]):禁用Nagle算法。默认情况下TCP连接使用Nagle算法,这些连接在发送数据之前对数据进行缓冲处理。 将noDelay设成true会在每次socket.write()被调用时立刻发送数据。noDelay默认为true
  • socket.setKeepAlive([enable], [initialDelay]):禁用/启用长连接功能,并在第一个在闲置套接字上的长连接probe被发送之前,可选地设定初始延时。enable默认为false

    设定initialDelay (毫秒),来设定在收到的最后一个数据包和第一个长连接probe之间的延时。设置为0会保留默认(或者之前)的值。默认为0

  • socket.address():返回Socket套接字绑定的IP地址, 协议类型以及端口号。其返回值是一个包含三个属性的对象, 形如{ port: 2345, family: 'IPv4', address: '127.0.0.1' }
  • socket.unref():如果当前套接字对象是事件系统中唯一一个活动的套接字,调用unref方法将允许程序退出。如果套接字已被 unref,则再次调用 unref 并不会产生影响。
  • socket.ref():与unref 相反。如果当前套接字对象是仅剩的套接字,在一个之前被 unref 了的套接字上调用 ref不会让程序退出(缺省行为)。如果一个套接字已经被 ref,则再次调用 ref 并不会产生影响。


5. Socket类中的属性

Socket套接字对象中有一些属性,用于查看对象相关状态。

  • socket.bufferSize:当前准备写入缓冲区的字符数,用户可根据此属性对数据流进行控制。遇到很大或增长很快的 bufferSize 时,用户可用尝试用pause()resume()来控制字符流。
  • socket.remoteAddress:远程的IP地址(TCP服务端),例如:'74.125.127.100''2001:4860:a005::68'
  • socket.remoteFamily:远程IP协议版本,例如:'IPv4''IPv6'
  • socket.remotePort:远程端口号,例如:8022
  • socket.localAddress:本地IP地址(TCP客户端),例如:'198.168.0.10'
  • socket. localPort:本地端口号,例如:8022
  • socket.bytesRead:客户端收到的字节数
  • socket.bytesWritten:客户端发送的字节数