node的网络通信

net,http,https

net模块

创建客户端

响应头和响应体应该使用两个换行隔开

createConnection(options,callback);

1
2
3
4
5
6
7
8
9
const net = require('net');

const socket = net.createConnection({
host: 'xyq135.com',
port: 80
}, () => {
console.log('连接成功!')
})

参数

options:配置参数

  • host:主机名
  • prot:端口号

callback:监听函数

callback:处理函数

返回值

返回值为:socket,是一个特殊的文件,
在node中变现为双工流对象:通过向流写入内容来发送数据,通过监听流的内容获取数据

创建服务端

net.createServer()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const net = require('net');

const server = net.createServer();

server.listen(9527);

server.on('listening', () => {
console.log('server正在监听9527')
})

server.on('connection', socket => {
console.log('有客户端连接!')
})

返回值

server对象。

server.listen(port)

监听每个端口

server.on(‘listening’,()=>{})

开始监听端口后触发的事件

server.on(‘connection’,socket=>{})

某个连接到来时触发该事件。
事件监听函数会获得socket对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const net = require('net');

const server = net.createServer();

server.listen(9527);

server.on('listening', () => {
console.log('server正在监听9527')
})

server.on('connection', socket => {
console.log('有客户端连接!')
socket.on('data', chunk => {
console.log('客户端请求:', chunk.toString('utf-8'));
})

socket.write(`HTTP/1.1 200 OK

<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
`)//响应给客户端的数据

socket.end();
})

http模块

http.request(url[, options][, callback])

发送请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
const http = require('http');

const request = http.request("http://nodejs.cn/api/http.html#httprequestoptions-callback", {
method: 'GET',
}, resp => {
console.log('状态码:', resp.statusCode);
console.log('响应头:', resp.headers);
let result = '';
resp.on('data', chunk => {
result += chunk.toString('utf-8');
})

resp.on('end', () => {
console.log('响应体:')
console.log(result);
})
})

request.end();

方法返回结果为可写流,需要使用request.write()写入请求体,使用request.end()结束写入。

http.createServer([options][, requestListener])

创建服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
const http = require('http');
const url = require('url');

const server = http.createServer((req, res) => {
console.log('有请求来了!')
console.log('请求地址:', req.url);
console.log('请求方法:', req.method);
console.log('请求头:', req.headers);

let body = '';
req.on('data', chunk => {
body += chunk.toString('utf-8')
})

req.on('end', () => {
console.log('请求体:');
console.log(body);
})

// 设置响应头信息
res.setHeader('name', 'xyq');
res.setHeader('lover', 'hsz');

// 设置响应码
res.statusCode = 404;

// 设置响应体
res.write('I love you!');
res.end();

})

server.listen(8080)

server.on('listening', () => {
console.log('正在监听8080')
})

客户端:

服务端

静态资源服务器(使用简单的readFile读取文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
const http = require('http');
const path = require('path');
const fs = require('fs');
const url = require('url');


const server = http.createServer(handleServer);

server.listen(9000);

server.on('listening', () => {
console.log('server listening 9000!');
})

/**
* 处理服务器函数
* @param {*} req
* @param {*} res
*/

async function handleServer(req, res) {
const requestUrl = req.url; //客户端请求的地址
const fileContent = await getFileContent(requestUrl);
if (!fileContent) {
// 文件存在
res.write(fileContent)
} else {
// 文件不存在
res.statusCode = 404;
res.write('sources is not exit!');
}
res.end();
}


/**
* 获取文件状态
*/
async function getState(filename) {
try {
return await fs.promises.stat(filename)
} catch {
return null;
}
}

/**
* 要处理的文件内容
* @param {String} requestUrl 路径
*/
async function getFileContent(requestUrl) {
const urlObj = url.parse(requestUrl);

let filename;
filename = path.resolve(__dirname, 'public', urlObj.pathname.substr(1));
let stat = await getState(filename);

if (stat) {
// 文件不存在
return null;
} else if (stat.isDirectory()) {
// 是一个目录
// 则继续请求目录下的index.html文件
filename = path.resolve(__dirname, 'public', urlObj.pathname.substr(1), 'index.html');
stat = await getState(filename);
if (!stat) {
// 文件不存在
return null;
} else {
// 文件存在,返回文件的内容
return await fs.promises.readFile(filename);
}
} else {
// 文件存在
return await fs.promises.readFile(filename);
}
}

搭建静态资源服务器(通过流来读取)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
const http = require('http');
const path = require('path');
const fs = require('fs');
const url = require('url');


const server = http.createServer(handleServer);

server.listen(9000);

server.on('listening', () => {
console.log('server listening 9000!');
})

/**
* 处理服务器函数
* @param {*} req
* @param {*} res
*/

async function handleServer(req, res) {
const requestUrl = req.url; //客户端请求的地址
const fileContent = await getFileContent(requestUrl, res);
if (!fileContent) {
// 文件不存在
res.statusCode = 404;
res.write('sources is not exit!');
res.end();
}
}


/**
* 获取文件状态
*/
async function getState(filename) {
try {
return await fs.promises.stat(filename)
} catch {
return null;
}
}

/**
* 要处理的文件内容
* @param {String} requestUrl 路径
*/
async function getFileContent(requestUrl, res) {
const urlObj = url.parse(requestUrl);

let filename;
filename = path.resolve(__dirname, 'public', urlObj.pathname.substr(1));
let stat = await getState(filename);

if (!stat) {
// 文件不存在
return null;
} else if (stat.isDirectory()) {
// 是一个目录
// 则继续请求目录下的index.html文件
filename = path.resolve(__dirname, 'public', urlObj.pathname.substr(1), 'index.html');
stat = await getState(filename);
if (!stat) {
// 文件不存在
return null;
} else {
// 文件存在,直接写入
readFileStream(filename, res);
return true;
}
} else {
// 文件存在
readFileStream(filename, res);
return true;
}
}

/**
* 通过获取文件名和写入流来将文件内容写入
* @param {*} filename
* @param {*} res
*/
function readFileStream(filename, res) {
const rs = fs.createReadStream(filename);

rs.on('data', chunk => {
const flag = res.write(chunk);
if (!flag) {
// 写入队列即将排满
rs.pause();
}
})

res.on('drain', () => {
rs.resume();
})

rs.on('end', () => {
res.end();
})
}

https协议

https协议保证数据在传输过程中不被窃取或篡改。

加密

对称加密

产生一个秘钥,既可以加密,又可以解密。

常用算法:DE3、3DES、AES、Blowfish

非对称加密

产生一堆秘钥,一个用于加密,一个用于解密。
一个公钥,一个私钥。

常用算法:RSA、Elgamal、Rabin、D-H、ECC。

https的默认端口是443。

https模块