nodejs——网络编程模块

来源:互联网 发布:大数据优缺点 编辑:程序博客网 时间:2024/06/04 18:51

nodejs学习笔记之网络编程

了解一下OSI七层模型
 
OSI层
功能
TCP/IP协议
应用层
文件传输,电子邮件,文件服务,虚拟终端
 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet
表示层
数据格式化,代码转换,数据加密
-
会话层
数据格式化,代码转换,数据加密
-
传输层
提供端对端的接口
TCP,UDP
网络层
为数据包选择路由
IP,ICMP,RIP,OSPF,BGP,IGMP
数据链路层
传输有地址的帧以及错误检测功能
SLIP,CSLIP,PPP,ARP,RARP,MTU
物理层
 以二进制数据形式在物理媒体上传输数据
ISO2110,IEEE802,IEEE802.2
 
主要内容
  • TCP(传输控制协议)
  • UDP(用户数据包协议)
  • HTTP(超文本传输协议)
  • Websocket
  • 网络服务与安全(cryto tls https)
 
 
TCP特征
 
  • 面向连接的协议 
  • 需要三次握手

 
TCP服务实践(一)
 
创建服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var net = require('net');
  
var server = net.createServer(function(socket) {
    //新的连接
    socket.on('data'function(data) {
        console.log('服务端接收到客户端的消息:' + data.toString());
        socket.write('服务端回应:你好');
    });
    socket.on('end'function() {
        console.log('服务端断开连接');
    });
});
  
server.listen(8124, function() {
    console.log('TCP服务创建');
});
 
TCP服务实践(二)
 
创建客户端:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var net = require('net');
  
var client = net.connect({port:8124}, function() {
    console.log('客户端连接成功');
    client.write('客户端发起问候:你好');
});
  
client.on('data'function(data) {
    console.log('客户端接收服务端消息:' + data.toString());
    client.end();
});
  
client.on('end'function() {
    console.log('客户端断开连接');
});
 
TCP服务的事件(一)
 
  • 服务器事件
    • listening:server.listen()
    • connection:net.createServer()
    • close:server.close()
    • error
 
 
TCP服务的实践(二)
 
  • 连接事件
    • data:一端执行write(),另一端触发该事件
    • end:任意一端断开连接,触发该事件
    • connect:该事件用于客户端,当套接字服务端连接成功时触发
    • drain:当任意一端触发write(),当前这端会触发该事件
    • error:当异常发生时,触发该事件
    • close:当套接字结束时,触发该事件
    • timeout:当一定时间后连接不再活跃时,触发该事件
 
 
TCP小结
 
  • 面向连接(建立通信线路:建立、使用、释放)
  • 三次握手(建立连接的过程)
  • nodejs实现(net模块)
 
UDP特征
 
  • 无连接
  • 不可靠的信息服务
  • 在网络差的情况,丢包严重
  • 既可以客户端发送消息,又可以做服务端接收消息
  • 使用场景:对丢包要求不高的场景(音频、视频、DNS服务)
 
UDP服务实践(一)
创建服务端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var dgram = require('dgram');
  
var server = dgram.createSocket('udp4');
  
server.on('message'function(msg, rinfo) {
    console.log('服务端获取信息:'+msg+'来自:'+rinfo.address+':'+rinfo.port);
});
  
server.on('listening'function() {
    var address = server.address();
    console.log('服务端正在监听:'+address.address+':'+address.port);
});
  
server.bind(41234);
 
UDP服务实践(二)
创建客户端:
1
2
3
4
5
6
7
8
9
var dgram = require('dgram');
  
var client = dgram.createSocket('udp4');
  
var message = new Buffer('我是客户端的消息');
client.send(message, 0, message.length, 41234, '127.0.0.1'function(err, bytes) {
    console.log('客户端发送完成,关闭客户端');
    client.close();
});
 
UDP套接字事件
  • message:当UDP套接字侦听网卡端口后,收到消息时会触发该事件,携带Buffer对象和远程地址信息
  • listening:当UDP开始侦听时,触发该事件
  • close:调用close()方法时,触发该事件
  • error:当出现异常时,触发该事件,如果不处理,会使进程退出
 
 
UDP小结
  • 面向无连接(不需要建立通信线路,把带有目的地址的包送到线路上)
  • 使用场景(对丢包要求不高,IP、UDP协议都是无连接的)
  • nodejs实现(dgram模块)
 
HTTP特征
  • 建立在TCP之上的应用层协议
  • 经典的模式:B/S
  • 知名HTTP标准:RFC2616(W3C和IETF)
 
HTTP服务实践(一)
1
2
3
4
5
6
7
8
9
创建服务端:
var http = require('http');
  
http.createServer(function(req, res) {
    res.writeHead(200, {'Content-type''text/plain'});
    res.end('Hello world!\n');
}).listen(8000);
  
console.log('服务器已开启');
 
HTTP报文
  • 第一部分:经典的TCP三次握手 
 
  • 第二部分:客户端(curl)发送请求报文
 
  • 第三部分:服务器响应(包含响应头和响应体)
 
  • 第四部分:结束会话
 
 
 
HTTP服务实践(二)
创建客户端:
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var http = require('http');
  
var options = {
    hostname: '127.0.0.1',
    port: 8000,
    method: 'GET',
    path: '/'
};
  
var req = http.request(options, function(res) {
    console.log('Status:'+res.statusCode);
    console.log('Headers:'+JSON.stringify(res.headers));
    res.setEncoding('utf-8');
    res.on('data'function(chunk) {
        console.log(chunk);
    });
});
  
req.end();
 
HTTP服务的事件(一)
  • 服务端事件 
    • connection 
    • request
    • close
    • checkContinue
    • connect
    • upgrade
    • clientError
 
HTTP服务的事件(二)
  • 客户端事件
    • response 
    • socket
    • connect
    • upgrade
    • continue
 
HTTP小结
  • HTTP建立在TCP之上的协议
  • 客户端的请求可以通过模拟完成(curl、http_client.js、浏览器等)
  • nodejs实现(http模块)
 
Websocket特征
  • 建立在http服务之上
  • 连接建立之后会upgrade至数据帧协议,进而实现服务端和客户端的交互
  • 全双工通信
 
Websocket实例(socketio)
 
socketio文档
socketio例子
 
 
Websocket小结
  • 全双工通信 
  • 创建http服务后会切换协议
  • nodejs实现(ws、socket.io模块)
 
网络服务与安全
安全连接的过程:
  • 根据数字证书进行认证
  • 进行加密传输
    • 交换公钥 
    • 客户端使用服务端的公钥进行加密
    • 服务端使用服务端私钥就行解密
    • 服务端使用客户端的公钥进行加密
    • 客户端使用客户端的私钥解密
 
 
网络编程小结
  • 了解OSI七层模型
  • 重点学习传输层(TCP、UDP)和应用层(HTTP、Websocket)协议的nodejs实现

  • 初步了解网络传输安全



nodejs——网络编程模块

net模块提供了一个异步网络包装器,用于TCP网络编程,它包含了创建服务器和客户端的方法。dgram模块用于UDP网络编程。

参考链接:https://nodejs.org/api/net.html, https://nodejs.org/api/dgram.html

一、TCP Server

net模块通过net.createServer方法创建TCP服务器,通过net.connect方法创建客户端去连接服务器。

1、通过net模块创建一个TCP Server

复制代码
// server.jsvar net = require('net');// 创建TCP服务器var server = net.createServer(function(socket) {    console.log('client connected');    // 监听客户端的数据    socket.on('data', function(data) {        console.log('server got data from client: ', data.toString());    });    // 监听客户端断开连接事件    socket.on('end', function(data) {        console.log('connection closed');    });    // 发送数据给客户端    socket.write('Hello\r\n');});// 启动服务server.listen(8080, function() {    console.log('server bound');});
复制代码

2、创建一个客户端

复制代码
// client.jsvar net = require('net');// 连接服务器var client = net.connect({port: 8080}, function() {    console.log('connected to server');    client.write('World!\r\n');});// 接收服务端的数据client.on('data', function(data) {    console.log('client got data from server: ', data.toString());    // 断开连接    client.end();});// 断开连接client.on('end', function() {    console.log('disconnected from server');});
复制代码

在一个终端运行TCP服务器代码,另一个终端运行TCP客户端代码,结果如下:

二、简易聊天室服务器

1、简易聊天室服务端

首先创建TCP服务器;然后是接收客户端连接请求;获取客户端发送过来的数据;允许多个客户端同时连接,所以需要接收所有的用户连接;服务器广播数据,把来自客户端的数据转发送给其他所有客户端;最后把关闭连接的客户端从服务器广播列表中给删除掉。

复制代码
// chatServer.jsvar net = require('net');//第一步 创建TCP服务器var server = net.createServer();// 存储所有客户端socket//第四步,服务器接收所有的用户连接
var sockets = [];
//第二步 接收客户端请求server.on(
'connection', function(socket) { console.log('Got a new connection');  //第五步,服务器广播数据 sockets.push(socket);  //第三步,获取客户端发送过来的数据 socket.on('data', function(data) { console.log('Got data: ', data); sockets.forEach(function(otherSocket) { if (otherSoecket !== socket) { otherSocket.write(data); } }); ]); // 第六步,关闭连接客户端从服务器广播列表删除 socket.on('close', function() { console.log('A client connection closed'); var index = sockets.indexOf(socket); sockets.splice(index, 1); });});server.on('error', function(err) { console.log('Server error: ', err.message);});server.on('close', function() { console.log('Server closed');});server.listen(8080);
复制代码

2、简易聊天室客户端 

先解释process模块

process模块是Node.js的一个全局模块,可以在任何地方直接使用而无需通过require方法引入。process模块允许获得或修改当前Node.js进程的设置。

process.stdin用于获取来自标准输入的可读流(Readable Stream)。

客户端代码

复制代码
// chatClient.jsvar net = require('net');process.stdin.resume();process.stdin.setEncoding('utf8');var client = net.connect({ port: 8080 }, function() {    console.log('Connected to server');    // 获取输入的字符串    console.log('input: ');    process.stdin.on('data', function(data) {        // 发送输入的字符串到服务器        console.log('input: ');        client.write(data);        // 输入 'close' 字符串时关闭连接        if (data === 'close\n') {            client.end();        }    });});// 获取服务端发送过来的数据client.on('data', function(data) {    console.log('Other user\'s input', data.toString());});client.on('end', function() {    console.log('Disconnected from server');    // 退出客户端程序    process.exit();});
复制代码

一个终端窗口执行$ node chatServer.js运行服务器代码。

另外两个终端窗口执行$ node chatClient.js运行客户端代码。

结果如下:


三、UDP编程 

UDP通过dgram.createSocket创建服务。

1、服务器端代码

复制代码
// udpServer.jsvar dgram = require("dgram");var server = dgram.createSocket("udp4");server.on("error", function(err) {    console.log("server error:\n" + err.stack);    server.close();});// 接收来自客户端的消息server.on("message", function(msg, rinfo) {    console.log("server got: " + msg.toString() + " from " + rinfo.address + ":" + rinfo.port);});// 监听服务server.on("listening", function() {    var address = server.address();    console.log("server listening on " + address.address + ":" + address.port);});server.bind(41234);// server listening 0.0.0.0:41234
复制代码

2、客户端

发送消息必须通过Buffer创建。

复制代码
// udpClient.jsvar dgram = require('dgram');var client = dgram.createSocket('udp4');var message = new Buffer('hello shiyanlou');client.send(message, 0, message.length, 41234, 'localhost', function(err, bytes) {    client.close();});
复制代码

运行结果如下

四、排错

1、Error: connect ECONNREFUSED 127.0.0.1:8080

服务器端口没开。

本文作者starof,因知识本身在变化,作者也在不断学习成长,文章内容也不定时更新,为避免误导读者,方便追根溯源,请诸位转载注明出处:http://www.cnblogs.com/starof/p/5056519.html有问题欢迎与我讨论,共同进步。 



0 0