Net 模块、HTTP 模块
参考
Net 模块
net 模块用于底层的网络通信,提供了基于流的 TCP 或 IPC 服务器和客户端的 API
TCP 服务在网络应用中十分常见,目前大多数应用都是基于 TCP 搭建的,TCP 的首要特性就是它是面向连接的。
net.Server 类
用于创建 TCP 或 IPC server
server 实例属性和方法
address()
返回服务器的地址,包括 port 端口号;family: ip版本;address: ip地址close()
方法,停止接受建立新的 connection ,如果 close 之前存在 connection 将会保存getConnections(callback)
方法,获取当前并发连接数,回调函数有两个参数,err: 错误信息;count: 并发数量listen()
启动一个 server 监听 ,当 server 开始监听,就会触发一个listening
事件,这个方法的最后一个参数 callback 将会被添加为listening
事件的监听器,参数(options[, callback])
options 参数包括port, host, path
等,也可以通过listen(path,callback)
监听一个路径,或者通过listen([port][,host][,callback])
启动一个 TCP 服务,监听 port 和 hostlistening
属性,表明 server 是否正在监听
server 实例的事件
listening
事件,调用 server.listen() 之后触发connection
事件,当一个新 connection 建立的时候触发,回调参数 socket 对象error
事件,错误出现的时候触发close
事件,当 server 关闭时触发,如果 connection 存在,直到所有 connection 结束才会触发
const net = require('net');
const PORT = 8867;
const HOST = '127.0.0.1';
const clientHandle = function (socket) {
const {port, address} = socket.address();
socket.on('data', function (data) {
console.log(address, port, 'on data');
socket.write('server is inline');
app.getConnections(function (error, connections) {
console.log(connections);
socket.destroy();
app.close();
})
})
}
const app = net.createServer(clientHandle);
app.listen(PORT, HOST, function () {
console.log('tcp server running', app.address());
console.log(app.listening);
});
app.on('listening', function () {
console.log('app is listening at ', app.address());
})
app.on('connection', function (socket) {
console.log('app is connection ', socket);
})
app.on('error', function (err) {
console.log('error', err);
})
app.on('close', function () {
console.log('app is close');
})
net.Socket 类
net.Socket 可以被用户创建并直接与 server 通信,在 server 中,当一个链接被接受时,可以通过监听
connection
事件触发而获得,可以使用它来与客户端通信
socket 实例的属性与方法
address()
返回操作系统报告的 socket 地址 address;端口:port;地址族:familyconnect()
方法,启动一个链接,参数(options[, listener])
options 参数包括port, host, path
等,也可以通过listen(path[, listener])
用于 IPC 链接,或者通过listen([port][,host][,listener])
启动一个 TCP 链接,返回值是 socket 自身connecting
属性,true:表示connect()
方法被调用但还未结束,false:在connect()
方法回调中会返回 falsedestroy()
方法,确保该 socket 上不在有 I/O 活动,一般用在错误部分destroyed
属性,指示链接是否已经被销毁end([data][, encoding])
半关闭 socket,如果指定 data 相当于先调用write()
方法发送数据,然后再调用end()
方法pause()
方法,暂停数据阅读resume()
方法,继续阅读数据setEncoding([encoding])
方法,设置编码write(data[,encoding],callback)
方法,发送数据setTimeout(timeout[, callback])
方法,设置超时时间
socket 实例事件
close
事件,一旦 socket 完全关闭就发出该事件connect
事件,socket 连接成功时触发data
事件,接收到数据时触发end
事件,当 socket 的另一端发送一个 FIN 包的时候触发,从而结束 socket 的可读端error
事件,当错误发生时触发timeout
事件,当 socket 超时的时候触发。该事件只是用来通知 socket 已经闲置。用户必须手动关闭。
const net = require('net');;
const PORT = 8867;
const HOST = '127.0.0.1';
const client = net.Socket();
client.setEncoding('utf-8');
client.connect(PORT, HOST, function () {
console.log('connect success.');
client.write('tcp client by node');
client.pause();
setTimeout(function () {
client.resume();
}, 1000)
})
console.log('connecting ', client.connecting); //true
client.on('data', function (data) {
console.log('received: ', data.toString());
})
client.on('connect', function () {
console.log('address', client.address());
console.log('connecting ', client.connecting); // false
console.log('localAddress', client.localAddress);
console.log('localPort', client.localPort);
console.log('remoteAddress', client.remoteAddress);
console.log('remoteFamily', client.remoteFamily);
console.log('remotePort', client.remotePort);
})
client.on('error', function (err) {
console.log('error', err);
client.end('ssssss');
client.destroy();
console.log('destroyed', client.destroyed);
})
net.createConnection()
一个工程函数,用来创建 net.Socket ,然后立即启动
connect()
方法,最终返回 socket 对象,有三种参数传入方式
net.createConnection(options[, connectListener])
options 与 socket 实例的connect
方法一致net.createConnection(path[, connectListener])
用来连接路径net.createConnection(port[, host][, connectListener])
连接 TCP
const client = net.createConnection(PORT, HOST, function () {
console.log('connect success.');
})
const client = net.createConnection({port: PORT, host: HOST}, function () {
console.log('connect success.');
})
net.createServer()
创建一个 TCP 或者 IPC 服务器,接受两个参数,第一个参数 options 可选, 第二个参数 connectionListener 监听函数,监听 connection
const app = net.createServer(function (socket) {
console.log(socket);
});
net.isIP()
判断某个字符串是不是ip 地址
net.isIP('10.0.0.1') // 4
net.isIP('cats') // 0
HTTP 模块
1. HTTP 模块属性和方法
METHODS
属性,返回解析器支持的 HTTP 方法列表STATUS_CODES
属性,返回标准的 HTTP 响应状态码集合及描述createServer([requestListener])
返回一个新建的 http.Server 实例,参数可以是一个request
事件处理函数request(options[, callback])
用于发出请求,options 可以是一个对象、字符串、或者 URL 对象,callback 参数可选,会作为单次监听器添加到responce
事件get(options[,callback])
因为大多数请求都是 GET 请求且不带请求主体,所以 Node.js 提供了该便捷方法
2. http.Server 类
继承 net.Server ,创建 服务器实例使用
http.createServer(callback)
1. server 实例的属性与方法
基本上继承了 net.Server 实例的方法与属性
listen()
启动一个 server 监听 ,当 server 开始监听,就会触发一个listening
事件,这个方法的最后一个参数 callback 将会被添加为listening
事件的监听器,参数(options[, callback])
options 参数包括port, host, path
等,也可以通过listen([port][,host][,callback])
监听listening
返回当前服务器是否正在监听链接close()
方法,停止服务器端接收新的链接setTimeout()
方法,设置超时时间timeout
属性,返回超时时间
2. server 实例的事件
connect
事件,当客户端发送 HTTP CONNECT 请求时触发,回调参数 request: HTTP 请求,同request
事件;socket: 服务器与客户端之间的网络 socket ; head 流的第一个数据包,可能为空connection
事件,当一个新的 TCP 流被建立时触发,回调参数 socketrequest
事件,每次接收到一个请求时触发,每个链接可能有多个请求,回调参数 request、responseupgrade
事件,每当客户端发送 HTTP upgrade 请求时触发
const http = require('http');
const PORT = 8867;
const HOST = '10.15.32.51';
const app = http.createServer(function (req, res) {
res.end('xxx');
})
app.listen(PORT, HOST, function () {
console.log('listen http ', PORT, HOST);
console.log('app.listening', app.listening);
})
app.on('connect', function (req, socket, head) {
console.log(req);
})
app.on('connection', function (socket) {
console.log('http connect ');
})
app.on('request', function (req, res) {
console.log('on request', res);
})
app.setTimeout(12000);
console.log(app.timeout);
app.on('timeout', function () {
console.log('timeout');
})
3. http.ClientRequest 类
该对象在 http.request() 内部被创建并返回。 它表示着一个正在处理的请求
1. request 实例的属性与方法
flushHeaders()
,刷新请求头getHeader(name)
获取请求头信息removeHeader(name)
移除某个请求头信息setHeader(name, value)
设置请求头信息setTimeout(timeout[, callback])
设置请求时长socket
返回底层 socket 的引用write(chunk[, encoding][, callback])
发送请求主体的一个数据块abort()
标记请求为终止aborted
如果请求终止则返回被终止的时间end([data[, encoding]][, callback])
结束发送请求。 如果部分请求主体还未被发送,则会刷新它们到流中
2. request 实例的事件
abort
事件,当请求已被客户端终止时触发。 该事件仅在首次调用 abort() 时触发。connect
事件,每当服务器响应 CONNECT 请求时触发,回调参数,response、socket、headcontinue
事件,当服务器发送了一个 100 Continue 的 HTTP 响应时触发response
事件,当请求的响应被接收到时触发。 该事件只触发一次。socket
事件,当 socket 被分配到请求后触发timeout
事件,请求超时时触发upgrade
事件,当服务器响应 upgrade 请求时触发
const http = require('http');
const querystring = require('querystring');
const PORT = 8867;
const HOST = '10.15.32.51';
const postData = querystring.stringify({
'msg' : 'Hello World!'
});
const options = {
hostname: HOST,
port: PORT,
method: 'GET',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
const request = http.request(options, function (res) {
// console.log(res);
});
request.setHeader('TEST', 'test header');
console.log(request.getHeader('TEST'));
request.removeHeader('TEST');
console.log(request.getHeader('TEST'));
request.flushHeaders();
request.setTimeout(12000);
request.on('abort', function () {
console.log('abort');
})
request.on('response', function () {
console.log('response');
})
request.on('timeout', function () {
console.log('timeout');
})
request.write('get somthing');
request.end('end', function () {
console.log('request end');
});
// request.abort();
// console.log(request.aborted);
3. http.createServer() 方法回调函数中的第一个参数 request 对象的属性、方法、事件
属性与方法
req.url
返回发出请求的网址req.method
返回 http 请求的方法req.headers
返回 http 请求的头信息setEncoding()
方法,设置请求的编码httpVersion
返回链接到的服务器的 http 版本rawHeaders
返回,接收到的原始的请求头列表
事件
aborted
事件,当请求已被终止且网络 socket 已关闭时触发。close
事件,当底层连接被关闭时触发。 同 ‘end’ 事件一样,该事件每个响应只触发一次。data
事件,接收到数据触发,回调参数,接受的数据
const http = require('http');
const fs = require('fs');
const PORT = 8867;
const HOST = '10.15.32.60';
const app = http.createServer(function (req, res) {
req.on('aborted', function () {
console.log('aborted');
})
req.on('close', function () {
console.log('close');
})
console.log(req.url);
console.log(req.method);
console.log(req.httpVersion);
console.log(req.statusCode);
console.log(req.statusMessage);
// console.log(req.headers);
req.on('data', function (postData) {
console.log(postData.toString());
res.write('xxx', function () {
res.end()
})
})
})
app.listen(PORT, HOST, function () {
console.log('listen http://' + HOST + ':' + PORT);
console.log('app.listening', app.listening);
})
4. http.ServerResponse 类
该对象在 HTTP 服务器内部被创建。 它作为第二个参数被传入 ‘request’ 事件
1. response 实例属性与方法
setHeader(name, value)
设置响应头的值,如果响应头已存在则会将其覆盖,如要设置多个同名响应头,value 的值可以是字符串数组hasHeader(name)
返回是否含有某个响应头getHeaderNames()
返回一个包含当前 http 头信息名称数组,均为小写getHeaders()
返回当前响应头文件的浅拷贝getHeader(name)
返回某个响应头信息headersSent
返回响应头是否被发送removeHeader(name)
移除响应头statusCode
属性,设置发送给客户端的状态码statusMessage
属性,控制发送给客户端的状态信息,默认为状态码的标准信息write(chunk[,encoding][,callback])
方法,可以被多次调用,用于设置返回的响应主体writeHead(statusCode[, statusMessage][, headers])
发送响应头,包括状态码和状态描述,只能被调用一次,会与 通过response.setHeader()
设置的响应头合并setTimeout(msecs[, callback])
设置超时时间finished
属性,表示响应是否已完成end([data][,encoding][,callback])
通知服务器所有响应头和响应主体都已被发送,每次响应都必须调用
2. response 实例事件
close
事件,end()
方法调用后触发finish
事件,当响应头与响应主体的最后一部分已被交给操作系统网络进行传输时触发,并不意味着客户端已经接受任何东西
const http = require('http');
const fs = require('fs');
const PORT = 8867;
const HOST = '10.15.32.60';
const app = http.createServer(function (req, res) {
res.on('close', function () {
console.log('close');
})
res.on('finish', function () {
console.log('finish');
})
res.setHeader('TEST', ['test1', 'test2']);
console.log(res.hasHeader('TEST'));
console.log(res.getHeaderNames());
console.log(res.getHeaders());
console.log(res.getHeader('TEST'));
console.log(res.headersSent);
res.removeHeader('TEST');
console.log('remove', res.hasHeader('TEST'));
res.writeHead(222, 'write head statue message', {
'TEST2': 'this is test header'
});
res.statusCode = 200;
res.statusMessage = 'test status message';
res.setTimeout(10000);
fs.readFile('./package.json', function (err, data) {
res.write(data, function () {
console.log('data write success');
res.end('xnxnxn');
console.log(res.finished);
})
})
})
app.listen(PORT, HOST, function () {
console.log('listen http://' + HOST + ':' + PORT);
console.log('app.listening', app.listening);
})