Node中的网络编程

Node的初衷就是建立一个高性能的Web服务器,这儿我们将着重于Node的网络编程。

注:前面我们讲解了Node的许多模块,如http,fs,path…但也有好多模块现在没有进行讲解(我们将在遇到的时候进行讲解),因为这些模块在实际使用中并不是那么频繁,希望大家自己去官网查看文档,这对理解学习Node有相当大的帮助,同时也是必经之路。

网络编程基本概念

通过使用套接字来达到进程间通信目的的编程就是网络编程
通常情况下,我们要使用网络提供的功能,可以有以下几种方式:

  1. 使用应用软件提供的网络通信功能来获取网络服务,如浏览器,它在应用层上使用http协议,在传输层基于TCP协议;

  2. 在命令行方式下使用shell 命令获取系统提供的网络服务,如telnet,ftp等;

  3. 使用编程的方式通过系统调用获取操作系统提供给我们的网络服务。

对于网络编程的基础,大概要从OSI的七层协议模型开始了,除了OSI模型还有TCP/IP 协议模型

OSI的七层协议模型

以FTP为例:

物理层到电缆连接,数据链路层到网卡,网络层路由到主机,传输层到端口,会话层维持会话,表示层表达数据格式,应用层就是具体FTP中的各种命令功能了。

在了解了这些之后,我们可以来看socket了。socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。也就是说socket(套接字)就是将操作系统中对于传输层及其以下各层中对于网络操作的处理进行了封装,然后提供一个socket对象,供我们在应用程序中调用这个对象及其方法来达到进程间通信的目的。

上面只是一个粗劣无比的介绍,推荐阅读一下文章:

Node 中的网络编程

Node.js也提供了对socket的支持,它提供了一个net(网络)模块用来处理和TCP相关的操作,提供了dgram模块用来处理UDP(数据报)相关操作

net 模块给你提供了一个异步的网络封装. 它包含创建服务器和客户端(称为流)的功能

1.创建TCP客户端

net模块通过net.createServer方法创建TCP服务器

  1. // server.js
  2. const net = require('net')
  3. // 创建TCP服务器
  4. const server = net.createServer((socket) => {
  5. console.log('客户端连接')
  6. // 监听客户端的数据
  7. socket.on('data', (data) => {
  8. console.log('监听客户端的数据: ', data.toString())
  9. });
  10. // 监听客户端断开连接事件
  11. socket.on('end', (data) => {
  12. console.log('客户端断开连接')
  13. });
  14. // 发送数据给客户端
  15. socket.write('哈哈哈,我是一个测试 \r\n')
  16. })
  17. // 启动服务
  18. server.listen(8080, () => {
  19. console.log('服务创建')
  20. })

2.创建客户端

通过net.connect方法创建客户端去连接服务器

  1. // client.js
  2. const net = require('net');
  3. // 连接服务器
  4. const client = net.connect({port: 8080}, () => {
  5. console.log('连接服务器');
  6. client.write('http://xingxin.me \r\n')
  7. })
  8. // 接收服务端的数据
  9. client.on('data', (data) => {
  10. console.log('接收服务端的数据: ', data.toString())
  11. // 断开连接
  12. client.end()
  13. })
  14. // 断开连接
  15. client.on('end', () => {
  16. console.log('断开连接')
  17. })

现在我们在命令行中执行

  1. $ node server.js
  2. # 再开一个命令行执行
  3. $ node client.js

你会看到如下结果

  1. $ node client.js
  2. 连接服务器
  3. 接收服务端的数据: 哈哈哈,我是一个测试
  4. 断开连接
  5. ####################################
  6. $ node server.js
  7. server bound
  8. 客户端连接
  9. 监听客户端的数据: http://xingxin.me
  10. 客户端断开连接

这儿我们介绍了使用Net模块创建Socket服务端与客户端,关于更多使用参见Node中文网

简易聊天室

前面我们介绍了网络编程以及Node中的实现,我们现在就成热打铁来写一个简易的聊天室

传送门GitHub

1. 聊天室的服务端

  1. const net = require('net')
  2. // 创建TCP服务器
  3. const server = net.createServer()
  4. // 存储所有客户端socket
  5. let sockets = []
  6. server.on('connection', function(socket) {
  7. console.log('Got a new connection')
  8. sockets.push(socket)
  9. socket.on('data', function(data) {
  10. console.log('Got data: ', data)
  11. sockets.forEach(function(otherSocket) {
  12. if (otherSocket !== socket) {
  13. otherSocket.write(data)
  14. }
  15. })
  16. })
  17. socket.on('close', function() {
  18. console.log('A client connection closed')
  19. let index = sockets.indexOf(socket)
  20. sockets.splice(index, 1)
  21. })
  22. })
  23. server.on('error', function(err) {
  24. console.log('Server error: ', err.message)
  25. })
  26. server.on('close', function() {
  27. console.log('Server closed')
  28. })
  29. server.listen(8080)

2. 聊天室的客户端

  1. const net = require('net')
  2. process.stdin.resume()
  3. process.stdin.setEncoding('utf8');
  4. const client = net.connect({ port: 8080 }, () => {
  5. console.log('Connected to server')
  6. // 获取输入的字符串
  7. console.log('input: ')
  8. process.stdin.on('data', (data) => {
  9. // 发送输入的字符串到服务器
  10. console.log('input: ')
  11. client.write(data)
  12. // 输入 'close' 字符串时关闭连接
  13. if (data === 'close\n') {
  14. client.end()
  15. }
  16. });
  17. });
  18. // 获取服务端发送过来的数据
  19. client.on('data', (data) => {
  20. console.log('Other user\'s input', data.toString())
  21. })
  22. client.on('end', () => {
  23. console.log('Disconnected from server')
  24. // 退出客户端程序
  25. process.exit()
  26. })

在命令行中node server.js创建一个服务器,然后用node client.js起多个客户端,便可以看见这个简陋的聊天小程序

相关阅读

抛砖引玉

最近一直没在状态,所以这个系列有好久没更新了,后续将加紧进度

后续计划:以构建一个完整的Node web框架来巩固前面的学习