本文是看王道和计算机网络微课堂所写,不过关于三次握手,四次挥手推荐大家看这篇文章,写得比较详细 https://www.cnblogs.com/biehongli/p/11964057.html
传输层是只有主机才有的层次
在五层体系中,传输层可以为应用层提供通信服务,也可以使用网络层的服务。
接下来看看传输层的功能:
①传输层提供进程和进程之间的逻辑通信(网络层提供的是主机之间的逻辑通信)
②复用和分用
举个生活中的例子来说明一下复用和分用。
比如说你们家有好多人同时都想要写信给你们的朋友,你们可以把信放在家门口的信箱,邮局会派人把信收集起来,收集完后,会派发出去,这就类似于复用
接下来说明一下分用
当各自写的信都收到了回复,信都 会放在门口的信箱中,然后我们取出来,分发给具体的每一个人,这就类似于分用
③传输层对收到的报文进行差错检测
④传输层的两种协议:TCP(可靠传输),UDP(不可靠传输)
先来回顾一下传输层的复用和分用这两个功能
复用:应用层所有的应用进程都可以通过传输层再传输到网络层
分用:传输层从网络层收到数据后交付发指明的应用进程
怎么指明应用进程呢?
在网络层和链路层,对于一个主机来说,我们如果想要发送信息给它,只需要网络地址和IP地址,找到对应的网络后,我们就得根据它对应MAC地址定位到具体哪一个主机,找到主机后,我们还得找到是这台主机的哪一个进程,这就涉及到传输层的问题,端口
端口(软件端口,是看不见摸不着的)是传输层的SAP,标识主机中的应用进程
端口号只有本地意义,它是为了标识本计算机应用层中的各个进程,在因特网中不同计算机的相同端口是没用联系的
端口号长度为16bit,能表示65535个不同的端口号
IP数据报首部中协议字段的值,表名了IP数据报数据载荷部分封装的是何种数据单元

17就是IP数据报首部的协议字段
在UDP伪首部中,包含32位源IP地址,32位目的IP地址,8位协议,16位UDP长度。通过伪首部的校验,UDP可以确定该数据报是不是发给本机的,通过首部协议字段,UDP可以确认有没有误传。






参与一条TCP连接的两个进程中的任何一个都鞥终止该连接,连接结束后,主机中的资源(缓存和变量)将被释放
在上面的图片中,左边是发送方,右边是接收方,发送方有多个报文段,首先发送方发送第一个报文段给接收方,也就是1,2,3字节构成的报文段,发过去以后,接收方就收到了,并且把它存储在自己的TCP缓存当中,并且寻找一个合适的时机把缓存中的报文段提交到上层,提交给应用层。
此时发送方的TCP缓存当中仍然有1,2,3字节构成的报文段,因为报文在发送过程可能出现丢失的情况,就导致接收方接收不到发送方发送的报文段,接收方就会要求发送方重传。因为接收方为了保证可靠传输,就必须保证发送方发送的信息它都能按序完整的接收到.所以这个报文段要在发送方的缓存中一直存在,直到接收方告诉发送方,它已经完整收到了,这样,发送方才可以把这个报文从缓存中删除。
那么发送方怎么样才能知道接收方完整而且正确的接收到呢?这就需要依靠我们的确认机制
接收方接收到报文段后,就会返回一个确认报文段,这个报文段是在合适的时候进行确认,我们一般是采用累积确认的方式,接收方在合适的时候发送一个只是起到确认作用的报文段。有的时候,接收方也可以在自己有信息发送的时候,把确认信息捎带上,也就是捎带确认
假设接收方发送的是一个只有确认功能的报文段
确认字段就是期待收到的下一个字节,刚刚接收方已经接收到1,2,3字节组成的报文段,那么接下来它就希望收到的是4字节开始的报文段
当发送方接收到了确认字段,就知道接收到已经接收到了自己刚刚发送的报文段,此时,它就可以把刚刚发送的报文段从自己的TCP缓存中删除
接下来,发送方就可以继续发送后面的报文段,比如发送4,5,6的报文段和7,8的报文段,可能因为网络的原因,此时,接收到只有接收到7,8组成的报文段
为了实现可靠传输,接收方会使用累计确认的方法
发送方接收到了确认报文后,就知道要重传4号报文段
TCP重传
确认重传不分家,TCP的发送方在规定时间(重传时间)内没有收到确认就要重传已经发送的报文段,这叫超时重传.
TCP的下层是互连网的环境,发送的报文段可能只经过一个高速率的局域网,也有可能是经过多个低速率的网络,每一个IP数据报选择的路由也是不一样的,取决于当时的网络,这就导致对于一个发送方来说,它发送的很多报文段走的路径不一样,经过的时间也不一样。
如果重传时间设置很短,就会导致很多报文不必要的重传
如果重传时间设置很长,会导致网络空闲的时间很长,减少传输效率。
TCP采用自适应算法,动态改变重传时间RTTs(加权平均往返时间)
这个时候,主机A不能发送报文给B,直到主机B重鑫发送一个新的窗口值,也就是B主机在接收缓存腾出位置,把缓存的一些数据上交给上层的应用层后,才可以继续接收数据,这个时候主机B给主机A发送一个接收窗口为400的报文段,但是这个报文段在发送的过程丢失了,A就会一直处于等待的状态,等待B可以发送一个让它可以继续发送数据的通知,B也一直在等待,等待A给它发送数据,因为B已经发送了通知,如果没有其他的措施的话,主机A和主机B就会一直等待,类似于操作系统的死锁。接下来看看采取什么方法解决这个问题
传输轮次是指发送方给接收方发送数据报文段后,接收方给发送方发回想应的确认报文段,一个传输轮次经历的时间其实就是往返时间(不是固定数值)
在TCP双方建立逻辑连接关系时,拥塞窗口的值被设置为1,传输轮次为0的拥塞窗口为1,此外,我们还得设置慢开始门限的初始值,假设为16。
在执行慢开始算法的时候,发送方每收到一个对新报文段的确认时,就把拥塞窗口值加1,然后开始下一轮的传输。
当拥塞窗口值增加到慢开始门限值时,就改为执行拥塞避免算法。由于发送方当前拥塞窗口值是1,而发送窗口值等于拥塞窗口值,所以发送方当前只能发送一个TCP数据报文段。换句话说,拥塞窗口是几,就能发送几个数据报文段
发送方收到后,把拥塞窗口中修改为16,此时,发送方的拥塞窗口值已经增大到了慢开始门限值,之后,我们要改用拥塞避免算法,也就是每个传输轮次结束后,拥塞窗口值只能线性加1,而不像慢开始算法那样,每个传输轮次结束后,拥塞窗口值按照指数规律增大
中间的过程类似,不再一一演示
由于部分报文段丢失,这就会导致超时重传
这里是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
我对如何计算通过{%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
给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[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
是否可以在不实际下载文件的情况下检查文件是否存在?我有这么大的(~40mb)文件,例如:http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm这与ruby不严格相关,但如果发件人可以设置内容长度就好了。RestClient.get"http://mirrors.sohu.com/mysql/MySQL-6.0/MySQL-6.0.11-0.glibc23.src.rpm",headers:{"Content-Length"=>100} 最佳答案
我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT
Ruby中如何“一般地”计算以下格式(有根、无根)的JSON对象的数量?一般来说,我的意思是元素可能不同(例如“标题”被称为其他东西)。没有根:{[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]}根包裹:{"posts":[{"title":"Post1","body":"Hello!"},{"title":"Post2","body":"Goodbye!"}]} 最佳答案 首先,withoutroot代码不是有效的json格式。它将没有包