这篇博客真的很详细很详细很详细,不打算试试看吗 > 。o
文章目录
而大多数时候,都是程序员自定义组织的协议~

约定:
常见组织格式:
实际开发会使用一些现成的格式:
标签的形式:< XXX > … </ XXX>

以{ }作为标识
内部有多个键值对,每个键值对之间用逗号分割
key与值之间使用冒号分割


其实并不准确,真实的报文应该是这样的:


可能有人会想,服务器不是远在天边的“服务我们的机器”吗?
http有个专属“座位“:80
并不是说这些端口号就代表了“远方服务器”的位置!
至于“专属座位”有什么用

报文长度:0~65535 => 64KB(64KB - 1B,近似64KB)
时代不同,现在64KB很小了,一个表情包都能几MB了~
要传输大数据
所以,UDP的数据报不宜过长,否则会出错
校验和:


校验和是通过复杂计算后的一个数值~


通过上述结构,也可以看出UDP并不在意数据传输是否成功~
核心机制,在于接收方收到了或者没有收到,都会有个应答,对传输失败有所动作
数据报报文结构:

可靠性不等于安全性

应答报文规则:
单条信息发送:

多条信息发送:


丢包在互联网里是一个很普遍的现象

丢包率如果达到10%,你基本上已经玩不了游戏了
如果发送方在一段时间后,迟迟没收到ACK,则发送方会判定为刚才的数据丢包了!
例如丢包率为10% ==> 丢包三次 0.1%,概率很低很低了,如果还丢包,那网络出现问题的概率更大!
所以,TCP处理这种多个包丢失的情况,仍然会超时重传
其实没有收到ACK有两种情况:
还记得TCP的序号机制吗
TCP太伟大了,T.T
这两个机制就是TCP的基石~
问:TCP是如何实现可靠性的?
但是,可靠性跟三次握手和四次挥手是有一点点关系的
一次握手 (handshake):一次交互
三次握手表示客户端和服务器之间,通过三次交互,建立了连接关系

小例子,小马和老马语音聊天:
如果老马不问,老马就不知道小马听不听得到它的声音
就是这个道理
客户端申请并要求服务器 “接受我的端请求和返回给我的响应”
服务器回复ack就相当于接受连接,承诺接受客户端请求和返回响应
客户端回复ack就相当于接受连接,承诺发送给服务器请求和接受服务器的响应
这合乎常理,发送申请不代表我已经连接到他了,只是试探,而对方接受申请则是肯定接受我的连接(go!我答应干活了)了,对方也要发送个申请来连接我,我再接受他的连接,才算是真正的“连接”(试探成功,我也要努力干活)
而服务器的ack和syn合成一个数据报一起发送,这是合理省事的,因为在双方未正式连接完之前,服务器也不需要做啥,一起发送是才是个明智的选择

第二位为1:ack报文 ==> 应答报文
第五位为1:syn报文 ==> 同步报文
第二位和第五位都为1:ack + syn报文
第六位为1:fin报文 ==> 结束报文
其他几个不讲~
为什么三次握手:

一样的:
一般来说,服务器那个线程是不会立马结束的,所以ack和fin分两次发

总流程:

TCP为了可靠性,牺牲了效率
单看效率,是完全比不上UDP的
批量发送:一次发多条数据,同时等待一个ack

批量发送不是无限制发送数据,而是发送到一定程度后,等待ack
而这个限制就是窗口的大小~

动图演示:

滑动窗口的丢包现象处理模式:
这种情况,完全没有影响,因为应答报文有个应答序号,其含义是其之前的数据都正常读到
动图演示:


动图演示:

而,如果批量发送太多,挤爆了缓冲区怎么办?
流量控制就是在批量发送的时候,限制滑动窗口的大小,不能导致接收方的缓冲区炸了
窗口越大 ==> 速度越快 ==> 更容易让缓冲区炸
缓冲区炸了,多余的数据全部丢包!在这里插入图片描述
所以流量控制能够保证一定的可靠性
机制:


此图的动图表示为:

但是实际上,实际的限制的窗口大小不等于缓冲区剩余的空间大小
真正的滑动窗口大小 = f ( 流量控制, 拥塞控制 )
流量控制:
拥塞控制:
我们知道,数据在互联网的传输路径上,会经过很多个路由器和交换机

就像耳熟能详的“木桶效应”:

真正的滑动窗口大小,应该是通过综合考虑到接收方缓冲区剩余空间,中间路径节点的个数和承受能力。
最好的方法就是:实验practice,实践出真理,通过实验找到一个合适的发送速率。


拥塞窗口:
实际窗口就是:min{拥塞窗口, 流量窗口}
TCP的可靠性核心为:确认应答
但是通过刚才对TCP的了解,决定传输效率的关键因素为“窗口大小”
实际窗口就是:min{拥塞窗口, 流量窗口}
相当于说:
别人发任务给我,我完成了一部分,不立马说我完成了一部分(那么它就会给我补一点任务),而是完成百分之70后才跟他说,这样压力就少很多~
这个ack延时发送后,窗口大小大概率是变大了的,因为这个过程里,接受方一直消耗接受缓冲区里的内容~
- 数量控制:每隔N个包就应答一次
- 时间控制:超过最大延时时间就应答一次
看情况处理,也有一些包是不会延时的
客户端服务器之间的通信,一般是 “一问一答” 的模式
对于一问一答的形式:

ack原本是立马返回的,但是结合延时应答,如果延时应答过程中,响应计算好了,或者时机很接近,那么ack就和响应一起打包发送,这就是捎带应答

所以说,四次挥手有时可能是三次挥完呢?

定义报与报之间的分割符,这就是一个有效方案
还有一个常见方案:约定数据的前4个字节(或者更多),表示整个数据报的长度
对方是发送方,对方就会收不到ack ==> 超时重传 ==> 重置连接 ==> 释放连接
对方是接收方,对方是没法立即知道,我这边是没来来得及发新的数据,还是我“死了”
我可能在控制台输入中呢~
TCP内置了心跳包的“保活机制”
就是说,对方是接收方,对方就会定期给我发一个心跳包(ping),我就返回一个(pong)
例子:
更多TCP的细节,可以查看这个标准文档:
RFC 9293: Transmission Control Protocol (TCP) (ietf.org)
TCP 可靠传输,效率没那么高,UDP不可靠传输,效率高~
两者的不同在于应用场景的不同
场景:既需要可靠性,又需要比较高的效率
文章到此结束!谢谢观看
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭🦆!网络原理尚未结束,IP协议紧随其后,敬请期待~
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳