第一次握手:客户端向服务器发送一个 SYN=1 报文,并指定客户端的初始化序列号 seq=x。此时客户端处于SYN_Sent 状态
第二次握手:服务器接收到客户端的 SYN=1 报文后,同意连接的话,会发出一段确定报文。确定报文中应该ACK= 1,SYN= 1,确认号是ack=x+1,同时也要为自己初始化一个序列号seq=y.此时服务器处于 SYN-RCVD
第三次握手:客户端接收到 SYN 报文之后,还会向服务器发送确定。确定报文的 ACK=1,ack=y+1 ,自己的序列号变成 x+1。TCP 连接建立,客户端处于 已连接状态 。
当服务器接受到客户端的确认后也进入了 已连接状态 。此时双方就可以开始通信了
为了防止失效的请求又传送到主机上,因而产生错误。
如果使用三次握手的话,就算是那一次失效的报文传送过来了,服务端收到这条失效报文并且回复确认报文,但是客户端不会再次发出确认。然后服务端收不到确认,就知道客户端并没有请求连接。
第一次挥手:客户端向服务端发送一个FIN报文,报文中指定一个序列号。此时,客户端处于 FIN_WAIT-1状态
第二次挥手:服务端收到客户端 发送的 FIN报文后,会将客户端的序列号+1 作为ACK报文的序列号值发送给客户端,表明收到了客户端的报文。然后服务器就会处于 CLOSE-WAIT-1状态
第三次挥手:服务端向客户端发送 FIN报文,且指定一个序列号。此时,服务端处于 LAST_ACK状态
第四次挥手:客户端收到服务端发送的FIN报文后,会将服务端的序列号+1 作为ACK报文的序列号值发送给服务端,此时客户端处于 TIME_WAIT 状态。需要等服务端确定收到自己的ACK报文后才会进入 CLOSED 状态
服务端接收到 ACK报文后,就关闭连接,处于 CLOSED 状态。
TCP是面向连接的传输层协议,UDP是无连接的传输层协议
TCP 是可靠传输,UDN是不可靠传输
TCP 传输数据是有序的,而UDP不保证数据的有序性
TCP不保存数据边界,UDP 会保存数据边界
TCP传输速度比UDP慢
TCP有流量控制和拥塞控制,UDP没有
TCP是重量级协议,首部较长,有二十个字节,UDP是轻量级协议,首部较短,只有八个字节
1xx:表示目前是协议的中间状态,还需要后续请求
2xx:表示请求成功
3xx:表示重定向状态,需要重新请求
4xx:表示请求报文错误
5xx:服务器端错误
常用状态码:
101 切换请求协议,从 HTTP 切换到 WebSocket
200 请求成功,有响应体
301 永久重定向:会缓存
302 临时重定向:不会缓存
304 协商缓存命中
403 服务器禁止访问
404 资源未找到
400 请求错误
500 服务器端错误
503 服务器繁忙
假设客户端向服务端发送两个数据包 A ,B
正常情况下,服务端会受到两个数据包,即没有发生拆分和粘包
第二种情况,服务端只会收到一个数据包,但是这个数据包中含有两个数据包的信息,这种情况就是因为接收端不知道这两个数据包的界限而产生的粘包。对于接收端来说很难处理
第三种情况,服务端收到了两个或者三个数据包的时候,有可能其中一个数据包分成了两个数据包,有可能是A中信息一部分到了B中信息,B中信息一部分到了A中信息。这种情况就是发生了拆包和粘包,对接收端来说同样是不好处理的
拆包和粘包解决方案
发送端为每个数据包添加包首部,首部中至少要包含数据包长度,这样接收端在接收到数据后,通过数据包长度就可以知道每个数据包的实际长度。
发送端将每个数据封装成固定长度(不够的就添0),这样接收端每次都读取固定长度的数据,自然而然的就会将每个数据包拆分出来
还可以在数据包之间设置边界,如添加特殊字符,这样接收端就可以通过这个边界把不同的数据包拆分出来了。
浏览器接收到url
浏览器会先查看缓存,如果有缓存且没有过期的话直接提供给客户端
否则浏览器就会通过DNS解析url ,获得协议名、主机名、端口号
然后浏览器就会根据这个IP跟对应的服务端建立tcp连接
接下来就是浏览器向服务器发送HTTP请求
服务器接受并解析这个请求然后发送一个数据包给浏览器
浏览器就会根据这个数据包解析HTML文档,构建DOM树,构建CSSOM树,解析js脚本,下载资源
最终就会显示出这个页面
输入域名时,操作系统会先检查自己本地host文件中是否有这个网址的映射关系,如果有,就调用这个IP地址映射,完成域名解析。
如果host没有这个域名的映射,则查找本地的DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
如果本地解析器缓存没有的话,则查找本地DNS服务器,如果要查询的域名包含在本地配置资源中,则完成域名解析。
如果本地DNS服务器没有的话,就会请求根服务器,根服务器就会返回一个负责该区域的主服务器IP
本地域名服务器根据主服务器IP,链接到这个主域名服务器,如果有这个域名的话,就调用这个IP地址映射,完成域名解析。如果没有的话,则递归请求下一级域名服务器,直到找到对应的域名
get 参数通过url 传递,post 放在 body中
get 传递参数有限制,post没有 (http协议规定,url在请求头中,所以大小有限制)
get 在浏览器回退时是无害的,而post会再次提交请求
get 请求会被浏览器主动 cache , 而 post 不会
get 比 post 更不安全, 因为参数直接暴露在url中,所以不能用来传递重要信息
get 只接受 ASCII,post 没有限制
get 产生一个 TCP数据包,post会产生两个 TCP数据包。对于 get 来说,浏览器会将 http 的 header 和 data 一起发送出去 服务器响应成功。 对于 post ,浏览器会先发送 header ,服务器响应继续,浏览器再发送 data ,服务器响应成功
HTTPS 协议需要 到CA 申请证书 ,一般需要交费
HTTP 协议运行在 TCP 上,所有传输内容都是明文。 HTTPS 运行在 SSL/TLS 之上,SSL/TLS运行在 TCP 上,所有传输内容都是经过加密的。
HTTP 和 HTTPS 使用的完全不同的连接方式,用的端口也不一样,前者用 80 后者用 443
HTTPS 能有效防止运营商劫持, 解决了一个防劫持的大问题。
多路复用:http2.0可以在一个 tcp/ip连接上并发的发送多个http 请求,不必等上一个http请求返回请求报文。http1.1要达到并发的话需要启用多个tcp/ip连接,会产生额外的性能开销。
头部压缩:http报文分为三部分,状态行、头部 、主体。http1.1 只会对主体进行压缩,不会压缩头部。http2.0 会使用hpack 算法对header 进行压缩。
服务器推送:http1.1浏览器在解析html 的时候会再次发送请求,请求css、js资源。http2.0浏览器在第一次请求html的时候就会检查html引用的资源,如果被引用的资源也在这台服务器上,服务器就会自动将被引用的资源推送给浏览器
二进制传输:http1.1 使用的是文本协议,http2.0 使用的二进制协议,会更加高效,而且错误更少
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
给定一个nxmbool数组:[[true,true,false],[false,true,true],[false,true,true]]有什么简单的方法可以返回“该列中有多少个true?”结果应该是[1,3,2] 最佳答案 使用转置得到一个数组,其中每个子数组代表一列,然后将每一列映射到其中的true数:arr.transpose.map{|subarr|subarr.count(true)}这是一个带有inject的版本,应该在1.8.6上运行,没有任何依赖:arr.transpose.map{|subarr|subarr.in
我正在构建一个应用程序,想知道是否将未使用的对象设置为nil是生产级编码中的常见做法。我知道这只是垃圾收集器的提示,并不总是处理对象。 最佳答案 根据这个thread如果您使用完一个成员对象,将其设置为nil将引发被引用对象被垃圾回收。如果它是局部变量,方法exit将做同样的事情。也就是说,如果您要求将成员显式设置为nil,我会质疑您的设计。 关于ruby-将对象设置为nil是否很常见?,我们在StackOverflow上找到一个类似的问题: https://
给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at