Nodejs-- 网络编程

网络编程

构建tcp服务

TCP

tcp全名为传输控制协议。再osi模型中属于传输层协议。
在这里插入图片描述

tcp是面向连接的协议,在传输之前需要形成三次握手形成会话
在这里插入图片描述

只有会话形成了,服务端和客户端才能想发送数据,在创建会话的过程中,服务端和客户端分别提供一个套接字。两个套接字共同形成一个连接, 服务端和客服端通过套接字实现两者的操作

创建TCP服务端

var net = require('net')
var server = net.createServer(function (socket) {// 新的连接socket.on('data',function(data) {socket.write('你好')})socket.on('end', function(data) {console.log('连接断开')})socket.write('welcome to the new world')
})
// 监听方式
server.listen(8124, function() {console.log('server bound')
})
// 新的连接
server.on('connection', function(socket) {
})

TCP服务的事件

服务器事件

对于net.createServer()创建的服务器而言,是一个eventEmitter实例,自定义的事件有如下几种

  1. listening: server.listen()绑定端口。
  2. connection: 每个客户端套接字连接到服务器端的时候触发。
  3. close: 当服务器关系触发的时候,在调用server.close()
  4. error: 当服务器发生异常的时候, 会触发该事件。
连接事件

服务端可以同多个客户端保持连接。对于每个连接而言都是典型的可读可写的stream对象。stream对象可以用于服务端和客户端之间的通信,既可以是通过data事件从一段到另一端发来的数据,也可以通过write方法从一段向另一端发送数据。

  1. data: 当一端通过write发送数据,另一端会触发data事件
  2. end: 当连接中的任意一端发送了FIN数据,当套接字和服务端成功会被触发
  3. connect: 该事件用于客户端,当套接字和服务端连接成功的时候会触发
  4. error: 当异常发生的时候,触发该事件
  5. close: 当套接字完全关闭的时候,触发该事件
  6. timeout: 当一定时间后连接不在活跃的时候,该事件会被触发。通知用户已经被闲置了
  7. drain: 当任意一段调用write发送数据时, 当前这端会触发该事件
    tcp套接字是可写可读的stream对象,可以利用pipe方法巧妙的实现管道操作
var net = require('net')
var server = net.createServer(function(socket){socket.write('Echo server')socket.pipe(socket)
})
server.listen(1337, '127.0.0.1')

TCP针对网络中的小数据包有一定的优化策略:Nagle算法。如果每次只发送一个字节的内容而不优化,网络中将充满只有极少数有效数据的数据包,将十分浪费网络资源。Nagle算法针对这种情况,要求缓冲区的数据达到一定数量或者一定时间后才将其发出,所以小数据包将会被Nagle算法合并,以此来优化网络。

构建UDP服务

UDP不是面向连接的。一个套接字可以与多个UDP服务通信,它虽然提供面向事务的简单不可靠信息传输服务,在网络差的情况下存在丢包严重的问题

创建UDP套接字

UDP套接字一旦创建,既可以作为客户端发送数据,也可以作为服务器端接收数据。

var dgram = require('dgram')
var socket = dgram.createSocket("udp4")

创建udp服务器端

var dgram = require('dgram')
var server = dgram.createSocket("udp4")
server.on("message", function(msg, rinfo){console.log("server got: " + msg + " from " +rinfo.address + ":" + rinfo.port);
})    
server.on('listening', function() {var address = server.address()console.log('server listening' + address.address + ":" + address.port)
})
server.bind(41234)

创建UDP客户端

var dgram = require('dgram')
var message = new Buffer('深入nodejs')
var client = dgram.createSocket("udp4")
client.send(message, 0, message.length, 41234, "localhost", function(err, bytes) {client.close()
})

api: socket.send(buf, offset, length, port, address, [callback])

upd套接字事件

  1. message: 收到信息的时候触发该事件,携带数据为消息buffer和一个远程地址信息
  2. listening: upd套接字来来时监听该事件
  3. close: 调用close可以触发该事件。不在触发message事件。
  4. error: 发生异常的时候触发该事件,不监听,异常之间抛出。

HTTP

curl -v http://127.0.0.1:1337 // tcp三次握手GET / HTTP/1.1  // 客服端发送请求报文
User-Agent: curl/7.24.0(x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8r zlib/1.2.5
Host: 127.0.0.1:1337
Accept: */* HTTP/1.1 200 OK // 服务端发送响应内容
Content-Type: text/plain
Date: Sat, 06 Apr 2013 08:01:44 GMT
Connection: keep-alive
Transfer-Encoding: chunkedhello world

基于请求响应式的,以一问一答的方式实现服务,虽然基于TCP会话,但是本身却并无会话的特点。
浏览器构造HTTP报文发向图片服务器端;然后,服务器端判断报文中的要请求的地址,将磁盘中的图片文件以报文的形式发送给浏览器;浏览器接收完图片后,调用渲染引警将其显示给用户。

http模块

Node的http模块包含对HTTP处理的封装。在Node中,HTTP服务继承自TCP服务器(net块 ),它能够与多个客户端保持连接,由于其采用事件驱动的形式,并不为每一个连接创建额外的线程或进程,保持很低的内存占用,所以能实现高并发
在开启keepalive后,一个TCP会话可以用于多次请求和响应。TCP服务以connection为单位进行服务,HTTP服务以request为单位进行服务。http模块即是将connection到request的过程进行了封装
在这里插入图片描述

http模块讲连接所用的套接字的读取抽象为ServerRequest和ServerResponse对象。分别对应请求和响应操作。在请求产生的过程中,http模块拿到连接中传来的数据,调用二进制模块http_parser进行解析,在解析完请求报文的报头之后,触发request时间,调用用户的业务逻辑。
在这里插入图片描述

function(req, res) {res.writeHead(200, {'Content-Type': 'text/plain'})res.end('hello wrold\n')
}

HTTP请求

对于TCP连接的读操作,http模块将其封装为ServerRequest对象。让我们再次查看前面的请求报文,报文头部将会通过http_parser进行解析。请求报文的代码如下所示:

GET /HTTP 1.1
User-Agent: curl/7.24.0(x86 64-apple-darwin12.0)libcurl/7.24.0 0penssL/0.9.8r zlib/1.2.5
Host: 127.0.0.1:1337
Accept: */*

报文体部分抽象一个只读流对象,如果业务逻辑需要读取报文体中的数据,数据流结束后才能进行操作

function (req, res) {var buffers = []req.on('data', function(trunk) {buffers.push(trunk);}).on('end', function() {var buffer = Buffer.concat(buffers)res.end('Hello world')    })
}

HTTP请求对象和HTTP响应对象是相对较底层的封装,现行的Web框架如Connect和Express都是在这两个对象的基础上进行高层封装完成的。

HTTP 响应

再来看看HTTP响应对象。HTTP响应相对简单一些,它封装了对底层连接的写操作,可以将其看成一个可写的流对象。它影响响应报文头部信息的API为res.setHeader()和res.writeHead()。

res.writeHead(200, {'Content-Type': 'text/plain'})
HTTP/1.1 200 OK
Content-Type: text/plain

只有调用writeHead后,报文才会写入到连接中,除此之外,http模块会自动帮你设置一些头信息

Date: Sat, 06 Apr 2013 08:01:44 GMT
Connection:keep-alive
Transfer-Encoding:chunked

报文体部分则是调用res.write()和res.end()方法实现,后者与前者的差别在于res.end()会先调用write()发送数据,然后发送信号告知服务器这次响应结束
响应结束后,HTTP服务器可能会将当前的连接用于下一个请求,或者关闭连接。值得注意的是,报头是在报文体发送前发送的,一旦开始了数据的发送,writeHead()和setHeader()将不再生效。
无论服务器端在处理业务逻辑时是否发生异常,务必在结束时调用res.end()结束请求,否则客户端将一直处于等待的状态。当然,也可以通过延迟res.end()的方式实现客户端与服务器端之间的长连接,但结束时务必关闭连接。

HTTP服务的事件

HTTP服务也抽象了一些事件,提供给应用层使用。同样典型的是,服务器是一个EventEmitter实例

  1. connect事件:在开始HTTP请求和响应前,客户端与服务器端需要建立底层的TCP连接,这个连接可能因为开启了keep-alive,可以在多次请求响应之间使用;当这个连接建立时,服务器触发一次connection事件。
  2. request事件: 建立TCP连接后,http模块底层将在数据流中抽象出HTTP请求和HTTP响应,当请求数据发送到服务器端,在解析出HTTP请求头后,将会触发该事件;在res.end()后,TCP连接可能将用于下一次请求响应。
  3. close事件: 与TCP服务器的行为一致,调用server.close()方法停止接受新的连接,当已有的连接都断开时,触发该事件;可以给server.close()传递一个回调函数来快速注册该事件。
  4. checkContinue: 某些客户端在发送较大的数据时,并不会将数据直接发送,而是先发送一个头部带Expect:100-continue的请求到服务器,服务器将会触发checkContinue事件;如果没有为服务器监听这个事件,服务器将会自动响应客户端100Continue的状态码,表示接受数据上传;如果不接受数据的较多时,响应客户端400Bad Request拒绝客户端继续发送数据即可
  5. connect事件:当客户端发起CONNECT请求时触发,而发起CONNECT请求通常在HTTP代理时出现;如果不监听该事件,发起该请求的连接将会关闭。
  6. upgrade事件:当客户端要求升级连接的协议时,需要和服务器端协商,客户端会在请求头中带上Upgrade字段,服务器端会在接收到这样的请求时触发该事件。
  7. clientError事件:连接的客户端触发error事件时,这个错误会传递到服务器端,此时触发该事件。

http客户端

node提供了基础的http和https模块用于http和https的封装

HTTP模块

在node中,http服务器继承自tcp服务器(net模块),能够和多个客户端保持连接,采用事件驱动的方式。不会为每一个连接创建额外的线程或者进程。在开启keepalive之后,一个tcp会话可以用于多个请求和响应,tcp服务以connection为单位进行服务,http服务以request为单位进行服务。
在这里插入图片描述

http模块将连接所用到的套接字的读写过程抽象为serverrequest和serverresopnse对象,分别对应请求和响应操作,在请求产生的过程中,http模块拿到连接传来的数据,调用二进制http_parser进行解析。解析完报文之后,触发request事件。
在这里插入图片描述

HTTP请求

对于TCP连接的读操作http模块将其封装为ServerRequest对象。分解为这些属性: 1. req.method 2. req.url 3. req.httpVersion

HTTP响应

res.setHeader, 可以进行多次设置,只有调用res.writedHead之后,才会写入连接中
res.writeHeader

HTTP服务的事件

服务器是一个EventEmitter实例

  1. connection事件: 在开始HTTP请求和响应之前,客户端和服务器需要建立底层的tcp连接。这个连接开启了keep-alive事件,可以在多个响应中使用,这个连接建立的时候,服务器触发一个connection事件
  2. request事件: 建立tcp连接之后,http模块底层将在数据流中抽象出http请求和http响应,当请求数据发送到服务器端,在解析出http请求报文之后,会触发该事件,在res.end()事件之后,tcp可能会用于下一次响应。
  3. checkContinue事件: 某些客户端在发送较大的数据之后,不会讲数据直接发送,发送continue(100)。服务器会触发checkCoutinue的事件,如果没有为服务器监听这个事件,服务器将会自动响应客户端100Continue的状态码,表示接受数据上传;如果不接受数据的较多时,响应客户端400Bad Request拒绝客户端继续发送数据即可。
  4. connect事件: 当客户端发起connect请求的时触发,发起connect请求通常在HTTP代理时候出现,如果不见听这个事件,发起该请求的连接就会关闭。
  5. upgrade事件: 当客户端要求升级连接协议的时候,需要和服务端协商。客户端才会在请求中带上upgrade字段
  6. clientError事件: 连接的客户端会触发error事件,这个错误会传递到服务器端。

HTTP客户端

  1. host: 服务器的域名和ip地址
  2. hostname: 服务器名称
  3. port: 服务器端口
  4. localAddress: 建立网络连接的本地网卡
  5. socketPath: Domain套接字连接路径
  6. method: http请求方法
  7. path: 请求路径,默认为/
  8. header: 请求头对象
  9. auth:basic认证,用于计算请求头中的Authorization部分
HTTP响应

HTTP客户端的响应对象和服务器端较为相似。

function(res) {res.setEncoding('utf-8')res.on('data', function(chunk) {console.log(chunk)})
}
http代理

在keepalive的情况下,一个底层会话可以用于多次请求,为了重用tcp连接,http模块包含了一个默认的客户端代理对象Http.globalAgent,对于服务器端的创建的连接进行了连接,实际上是一个线程池。
在这里插入图片描述

调用HTTP客户端同时对一个服务器发起10个HTTP请求uid时候,实际上是只有5个请求处于并发状态,后续的请求需要等待某个请求完成服务后真正发出。

http客户端事件
  1. response
  2. socket:当底层连接池中建立的连接分配给当前请求对象时,触发该事件。
  3. connect:当客户端向服务器端发起CONNECT请求时,如果服务器端响应了200状态码,客户端将会触发该事件。
  4. upgrade:客户端向服务器端发起Upgrade请求时,如果服务器端响应了101 SwitchingProtocols状态,客户端将会触发该事件。
  5. continue:客户端向服务器端发起Expect:100-continue头信息,以试图发送较大数据量如果服务器端响应100 Continue状态,客户端将触发该事件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/338394.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于如何通过APlayer+MetingJS为自己的wordpress博客网页添加网易音乐播放器(无需插件)

本文转自博主的个人博客:https://blog.zhumengmeng.work,欢迎大家前往查看。 原文链接:点我访问 序言:最近在网上冲浪,发现大家的博客大部分都有一个音乐播放器能够播放音乐,随机我也开始寻找解决方法。可是找来找去我…

已解决java.nio.charset.CoderMalfunctionError: 编码器故障错误的正确解决方法,亲测有效!!!

已解决java.nio.charset.CoderMalfunctionError: 编码器故障错误的正确解决方法,亲测有效!!! 亲测有效 报错问题解决思路解决方法1. 检查和清理输入数据2. 选择正确的字符集3. 处理异常情况4. 更新Java版本或库5. 检查第三方库的依…

Java | Leetcode Java题解之第123题买卖股票的最佳时机III

题目&#xff1a; 题解&#xff1a; class Solution {public int maxProfit(int[] prices) {int n prices.length;int buy1 -prices[0], sell1 0;int buy2 -prices[0], sell2 0;for (int i 1; i < n; i) {buy1 Math.max(buy1, -prices[i]);sell1 Math.max(sell1, b…

p2p文件传输小工具

使用webRTC的相关技术栈可以很轻松的开发一个p2p文件传输工具&#xff0c;这里主要讲下使用datachannel开发的一个文件传输工具client程序的使用 客户端A&#xff1a;需要可以访问公网&#xff0c;运行client的主机 客户端B&#xff1a;可以访问公网&#xff0c;可以和客户端…

【Linux】 深入讲解自动化构建工具

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Linux一系列的文章&#xff08;质量分均在93分 以…

JavaScript倍速播放视频

F12打开开发者工具&#xff0c;打开控制台&#xff0c;输入这行代码&#xff0c;视频即可加速播放&#xff0c; 可以调整倍速&#xff08;2&#xff0c;4&#xff0c;8&#xff0c;16&#xff09; document. getElementsByTagName("video")[0]. playbackRate16

数论1---整除

概念与基本性质就不说了 例题1&#xff1a;已知a|n&#xff0c;b|n.且axby1,求证&#xff1a;ab|n 即&#xff1a; 所以&#xff1a;ab|n 例题2&#xff1a;设m是一个大于2的正整数&#xff0c;证明&#xff1a;对于任意正整数n&#xff0c;都有 由于我不想打公式了直接拍照…

基于 IP 的 DDOS 攻击实验

一、介绍 基于IP的分布式拒绝服务&#xff08;Distributed Denial of Service, DDoS&#xff09;攻击是一种利用大量受控设备&#xff08;通常是僵尸网络&#xff09;向目标系统发送大量请求或数据包&#xff0c;以耗尽目标系统的资源&#xff0c;导致其无法正常提供服务的攻击…

[图解]企业应用架构模式2024新译本讲解06-表模块3

1 00:00:00,800 --> 00:00:03,470 接下来&#xff0c;我们来看这个序列图 2 00:00:04,400 --> 00:00:05,740 因为序列图比较大 3 00:00:06,180 --> 00:00:09,770 我们就不好放在幻灯片里面来看了 4 00:00:11,060 --> 00:00:12,130 下面还有很多 5 00:00:13,950…

制作ChatPDF之Elasticsearch8.13.4搭建(一)

Elasticsearch8.x搭建 在Windows系统上本地安装Elasticsearch的详细步骤如下&#xff1a; 1. 下载Elasticsearch 访问 Elasticsearch下载页面。选择适用于Windows的版本8.13.4&#xff0c;并下载ZIP文件。 2. 解压文件 下载完成后&#xff0c;找到ZIP文件&#xff08;例如…

实操专区-第15周-课堂练习专区-漏斗图与金字塔图

实操专区-第15周-课堂练习专区-漏斗图 下载安装ECharts&#xff0c;完成如下样式图形。 代码和截图上传 基本要求&#xff1a;下图3选1&#xff0c;完成代码和截图 完成 3.1.3.16 漏斗图中的任务点 基本要求&#xff1a;2个选一个完成&#xff0c;多做1个加2分。 请用班级学号姓…

mybatis增删改查模板设置及设置调用

mybatis增删改查模板设置 系统配置文件完成以及连接好数据之后&#xff0c;就可以用这个mybatis了&#xff0c;首先写这个数据库的增删改查模板StashMapper.xml&#xff0c;这个东西是要放在DAO层中的奥&#xff0c;切记。 1.编写mybatis对应数据库的增删改查模板 在我的Sta…

SSL发送邮件时如何配置客户端确保安全性?

怎么使用SSL安全协议通过AokSend发送加密的电子邮件&#xff1f; SSL是一种常用的加密通信协议&#xff0c;用于确保数据在客户端和服务器之间的安全传输。AokSend将讨论如何通过配置客户端确保SSL发送邮件的安全性&#xff0c;并介绍如何使用SSL安全协议通过AokSend发送加密的…

IDEA中,MybatisPlus整合Spring项目的基础用法

一、本文涉及的知识点【重点】 IDEA中使用MybatisPlus生成代码&#xff0c;并使用。 Spring整合了Mybatis框架后&#xff0c;开发变得方便了很多&#xff0c;然而&#xff0c;Mapper、Service和XML文件&#xff0c;在Spring开发中常常会重复地使用&#xff0c;每一次的创建、修…

翼龙面板是什么,如何进行搭建

翼龙面板是一个开源的&#xff0c;用于游戏服务器管理的程序&#xff0c;可以方便地在网页界面中创建Minecraft&#xff0c;起源引擎游戏和Teamspeak3 服务器。 它使用前后端程序&#xff0c;因此可以创建多后端节点&#xff0c;对游戏服务器和服务器节点进行统一管理。 对游戏…

java项目之智能家居系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的智能家居系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于Springboot的智能家居系…

WPS部分快捷操作汇总

记录一些个人常用的WPS快捷操作 一、去除文档中所有的超链接&#xff1a; 1、用WPS打开文档&#xff1b; 2、用Ctrla全选&#xff0c;或者点击上方的【选择】-【全选】&#xff0c;选中文档全部内容&#xff1b; 3、按CTRLSHIFTF9组合键&#xff0c;即可一次性将取文档中所有…

yolov10/v8 loss详解

v10出了就想看看它的loss设计有什么不同&#xff0c;看下来由于v8和v10的loss部分基本一致就放一起了。 v10的论文笔记&#xff0c;还没看的可以看看&#xff0c;初步尝试耗时确实有提升 好记性不如烂笔头&#xff0c;还是得记录一下&#xff0c;以免忘了&#xff0c;废话结束…

[数据集][目标检测]数据集VOC格式岸边垂钓钓鱼fishing目标检测数据集-4330张

数据集格式&#xff1a;Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;4330 标注数量(xml文件个数)&#xff1a;4330 标注类别数&#xff1a;1 标注类别名称:["fishing"] 每…

基于LQR控制算法的电磁减振控制系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 5.完整工程文件 1.课题概述 基于LQR控制算法的电磁减振控制系统simulink建模与仿真。仿真输出控制器的收敛曲线。 2.系统仿真结果 3.核心程序与模型 版本&#xff1a;MATLAB2022a 08_029m 4.系统原理…