net 模块
1 | var net = require("net"); |
此模块提供 TCP/UDP Socket 通信,dns 查询等等基本网络功能
Socket
- IP 地址,32 位,4byte,每个 byte 用逗号分隔,最大也就是 FF,FF,FF,FF 即 255,255,255,255
- port,端口,16 位,2 个 byte 构成,最大 FFFF = 65535 个, 0-1023 是 著名端口,例如 HTTP 的 80,HTTPS 的 443 端口,别冲突了
net.Socket 类型,表示 socket 实例
TCP 通讯
net.Server
net.createServer
1 | net.createServer([options], [connectionListener]); |
第一个参数表示创建服务器的选项,allowHalfOpen,如果为 true,当客户端断开连接的时候,server 还保持该连接,这种情况下,server 应该总是显示关闭连接
第二个参数,是一个 connection 事件的 listener
1 | var net = require("net"); |
创建好的是net.Server
实例
net.Server listen
创建好 server 之后,需要绑定到端口,也就是监听某一端口
1 | server.listen(port, [host], [backlog], [callback]); |
第一个参数端口,传 0 或忽略表示随机选择一个端口
后面是 host,表示只接受这个 host 的请求
第三个表示请求队列的容量,默认 511,如果队列满了之后,就不再接受新的请求
最后 callback,是 listening 事件的监听器
net.Server address
一旦绑定端口成功,就可以调用 address 方法来获取绑定的 host 和 port,同时还有 family 字段,表示 IPv4 or IPv6,如果开始传的是 0 也就是随机取端口的话,现在可以显示处理,到底使用的是哪一个端口
1 | { address: '::1', family: 'IPv6', port: 64269 } |
net.Server close
close 事件,以及 close 方法,都是 server 实例的,不要跟 socket 的 close 事件搞混
1 | var net = require("net"); |
net.Server ref/unref
在之前 setTimeout/setInterval 那说过,server 的事件循环使程序不会退出,使用 unref()来改变这种情况,ref()反向操作
net.Server error 事件
server 遇到错误时,例如要绑定的端口正在被使用,引发 err,err.code = "EADDRINUSE"
1 | server.on("error", function(error) { |
net.Socket 处理请求
也就是前面说的 server 的 connection 事件,参数是net.Socket
实例
socket
有 write/end 方法写入数据
有 data/end/close/error 事件接受数据,判断 client 状态
有 pause/resume/pipe 这些 stream 的特征
socket 联系这 server 与客户端
使用localAddress
,localPort
获取 server 的信息
使用remoteAddress
,remotePort
获取客户端的信息
当客户端突然关闭的时候,socket 会触发 error 事件,err.code = "ECONNRESET"
,再接着引发 socket 的 close 事件,注意在多人聊天时移除客户端,不要移除两次
1 | arr.splice(index, 1); //移除index位置 |
客户端
net.connect 创建客户端
1 | var client = net.connect(port, [host], [connectListener]); |
第三个参数是 connect 事件的监听器,表示连接上了
重载,除了指定 port host 之外,还可以用一个 plain object 代替,字段有 :
port host allowHalf localAddress
data 事件
1 | //client.pipe(process.stdout); //输出到console 要换行啊 |
可以直接 client.pipe(process.stdout),但是数据不换行啊,还能不能愉快地阅读了…
error close 事件
发生错误的话,引发 error 事件,接着引发 close 事件…
像服务器要是突然挂了的话,也是 error,err.code = "ECONNRESET"
,连接重置 ?
TCP 实现多人聊天
中文乱码问题根本原因是 win7 的控制台是 gbk 编码,所以在 process.stdin data 事件从源头解决,其他地方不用管编码,一路 utf8
实现截图
服务器 chat-server.js
1 | var net = require("net"); |
客户端 chat-client.js
1 | var net = require("net"); |
UDP 通讯
UDP,是 user datagram protocol,用户数据电报协议,TCP 是面向连接的,可靠的,TCP 不是,所以 TCP 不那么可靠,但是它快,应用在允许适量丢包的情况,如音视频通话啦…
1 | var dgram = require("dgram"); |
因为不用连接,只要发送数据就可以了,不管对方有没有收到…
send(buffer 数据,buffer 偏移,发送长度,端口,地址,回调),用到再查吧…那么长
封装 send 函数,address,port 更符合我的逻辑
1 | var udp = require("dgram"); |
DNS
将域名翻译成 IP,访问
dns.lookup
1 | dns.lookup(domin,4 or 6,callback(err,result)); |
dns.reverse
根据 IP 查域名
dns.resolve(domin,record_type,callback)
以及dns.resolveXXX()
变种
与 lookup 的区别是,resolve 支持各种类型的记录,A 记录/cname 记录/MX 邮件记录 什么的一堆
net.isIp()/isIPv4/isIPv6
判断是否是合法的 IP 地址