网络传输层之TCP、UDP详解

1、传输层存在的必要性

       由于网络层的分组传输是不可靠的,无法了解数据到达终点的时间,无法了解数据未达终点的状态。因此有必要增强网络层提供服务的服务质量。

2、引入传输层的原因

       面向连接的传输服务与面向连接的网络服务类似,都分为建立连接、数据传输、释放连接三个阶段;编址、寻址、流控制也是类似的。无连接的传输服务与无连接的网络服务也非常类似。一个很显然的问题:既然传输层的服务与网络层的服务如此相似,那么为什么我们还要两个独立的层呢?

      原因在于:传输层的代码完全运行在用户的机器上,但是网络层主要运行在由承运商控制的路由器上。试想以下几种情况?

       网络层提供的服务不够用;

       频繁的丢失分组;

       路由器时常崩溃。

       用户在网络层上并没有真正的控制权,所以他们不可能用最好的路由器或者在数据链路层上用更好的错误处理机制来解决服务太差的问题。唯一的可能是在网络层之上的另一层中提高服务质量。这就是传输层存在的必要性

      传输层的重要性:不仅仅是另外一层,它是整个协议层次的核心所在。如果没有传输层,那么分层协议的整个概念将变得没有意义。

      传输层的任务:在源机器和目标机器之间提供可靠的、性价比合理的数据传输服务,并且与当前使用的物理网络完全独立。

 

3、传输层的功能

        数据传送,不关心数据含义,进程间通信。

        弥补高层(上3层)要求与网络层(基于下3层)数据传送服务质量间的差异(差错率、差错恢复能力、吞吐率、延时、费用等),对高层屏蔽网络层的服务的差异,提供稳定和一致的界面。

4、传输层协议与网络层协议的主要区别

       网络层(IP层)提供点到点的连接即提供主机之间的逻辑通信,传输层提供端到端的连接——提供进程之间的逻辑通信

5、传输层的用途

      传输层将数据分段,并进行必要的控制,以便将这些片段重组成各种通信流。在此过程中,传输层主要负责:

       跟踪源主机和目的主机上应用程序间的每次通信;

       将数据分段,并管理每个片段;

       将分段数据重组为应用程序数据流;

       标识不同的应用程序。

6、端口号的概念

        运行在计算机中的进程是用进程标识符来标志的。运行在应用层的各种应用进程却不应当让计算机操作系统指派它的进程标识符。这是因为在因特网上使用的计算机的操作系统种类很多,而不同的操作系统又使用不同格式的进程标识符。为了使运行不同操作系统的计算机的应用进程能够互相通信,就必须用统一的方法对TCP/IP体系的应用进程进行标志。

解决这个问题的方法就是在运输层使用协议端口号(protocol port number),或通常简称为端口(port)

虽然通信的终点是应用进程,但我们可以把端口想象是通信的终点,因为我们只要把要传送的报文交到目的主机的某一个合适的目的端口,剩下的工作(即最后交付目的进程)就由 TCP来完成。

  

 

7、传输层的主要协议

          TCP/ IP传输层的两个主要协议都是因特网的重要标准,传输控制协议TCPTransmission Control Protocol[RFC 768]、用户数据报协议UDPUser Datagram Protocol[RFC 793]

          传输层的数据流要在网络端点之间建立逻辑连接。如果使用UDP,传输层的首要任务是将数据从源设备传输到目的设备。如果使用TCP,传输层主要通过滑动窗口来提供端到端控制,以及利用确认序列号和确认信息提供可靠性。传输层定义主机应用程序之间端到端的连接。

 

8TCP&UDP的比较

       TCPTransmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。

       UDPUser Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)

 问题1:什么是面向连接、面向无连接?

        面向连接举例:两个人之间通过电话进行通信。

面向无连接举例:邮政服务,用户把信函放在邮件中期待邮政处理流程来传递邮政包裹。显然,不可达代表不可靠。

         从程序实现的角度解析面向连接、面向无连接如下:

         TCP面向连接,UDP面向无连接(在默认的阻塞模式下):

         在TCP协议中,当客户端退出程序或断开连接时,TCP协议的recv函数会立即返回不再阻塞,因为服务端自己知道客户端已经退出或断开连接,证明它是面向连接的;

        而在UDP协议中,recvfrom这个接收函数将会始终保持阻塞,因为服务端自己不知道客户端已经退出或断开连接,证明它是面向无连接的)。

 

       从上图也能清晰的看出,TCP通信需要服务器端侦听listen、接收客户端连接请求accept,等待客户端connect建立连接后才能进行数据包的收发(recv/send)工作。

         而UDP则服务器和客户端的概念不明显,服务器端即接收端需要绑定端口,等待客户端的数据的到来。后续便可以进行数据的收发(recvfrom/sendto)工作。

问题2:什么是面向字节流、面向报文?

       面向字节流:虽然应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就可以把它划分短一些再传送。如果应用程序一次只发送一个字节,TCP也可以等待积累有足够多的字节后再构成报文段发送出去。

       面向报文:面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层需要分片,降低效率。若太短,会是IP太小。(谢希仁,第五版。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送),即一次发送一个报文)。

问题3:在默认的阻塞模式下,为什么说TCP无边界,UDP有边界?

         对于TCP协议,客户端连续发送数据,只要服务端的这个函数的缓冲区足够大,会一次性接收过来,即客户端是分好几次发过来,是有边界的,而服务端却一次性接收过来,所以证明是无边界的;

        而对于UDP协议,客户端连续发送数据,即使服务端的这个函数的缓冲区足够大,也只会一次一次的接收,发送多少次接收多少次,即客户端分几次发送过来,服务端就必须按几次接收,从而证明,这种UDP的通讯模式是有边界的。

问题4:UDP 如何发送大量的数据?如何处理分包?

        用 updclient 一次不能发送太大的数据量,不然就会报错:一个在数据报套接字上发送的消息大于内部消息缓冲器或其他一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。但不知道一次到底能发多少字节?如果把一个大的字节数组拆分成若干个字节数组发送,那么接收时如何判断和处理呢?

       答:方法很简单:

1、在客户端将你要发送的内容(文件什么的都可以)分块,每块内容进行编号,然后发送;

2、服务端在接收到你的分块数据以后,根据你的客户端数据内容的编号重新组装

3、一般我们在发送数据的时候,尽量采用比较小的数据块的方式(我的都没有超过1024的),数据块太大的话容易出现发送和接收的数据时间长,匹配出问题。

问题5.UDP发包的问题

       问:udp发送两次数据,第一次 100字节,第二次200字节,接包方一次recvfrom( 1000 ),收到是 100,还是200,还是300

       答:UDP是数据报文协议,是以数据包方式,所以每次可以接收100200,在理想情况下,第一次是无论recvfrom多少都是接收到100。当然,可能由于网络原因,第二个包先到的话,有可能是200了。对可能会由于网络原因乱序,所以可能先收到200,所以自定义的udp协议包头里都要加上一个序列号,标识发送与收包对应。

问题6.TCP的发包问题

       问:同样如果换成tcp,第一次发送 100字节,第二次发送200字节,recv( 1000 )会接收到多少?

       答:tcp是流协议,所以recv( 1000 ),会收到300 tcp自己处理好了重传,保证数据包的完整性

问题7.有分片的情况下如下处理

        问:如果MTU1500,使用UDP发送 2000,那么recvfrom(2000)是收到1500,还是2000?

        答:还是接收2000,数据分片由ip层处理了,放到udp还是一个完整的包。接收到的包是由路由路径上最少的MTU来分片,注意转到UDP已经在是组装好的(组装出错的包会经crc校验出错而丢弃),是一个完整的数据包。

问题8.分片后的处理

       问:如果500那个片丢了怎么办?udp又没有重传

       答:udp里有个crc检验,如果包不完整就会丢弃,也不会通知是否接收成功,所以UDP是不可靠的传输协议,而且TCP不存在这个问题,有自己的重传机制。在内网来说,UDP基本不会有丢包,可靠性还是有保障。当然如果是要求有时序性和高可靠性,还是走TCP,不然就要自己提供重传和乱序处理(  UDP内网发包处理量可以达7M~10M/s )

问题9.不同连接到同一个端口的包处理

       问:TCP

          A -> C100

          B -> C200

         AB同时同一端口

         C recv(1000) ,会收到多少?

      答:AC是一个tcp连接,BC又是另一个tcp连接,所以不同socket,所以分开处理。每个socket有自己的接收缓冲和发送缓冲

问题10.什么是TCP粘包

        在应用开发过程中,基于TCP网络传输的应用程序有时会出现粘包现象(即发送方发送的若干包数据到接收方接收时粘成一包)。详细解释如下:由于TCP是流协议,对于一个socket的包,如发送 10AAAAABBBBB两次,由于网络原因第一次又分成两次发送, 10AAAAABBBBB,如果接包的时候先读取10(包长度)再读入后续数据,当接收得快,发送的慢时,就会出现先接收了 10AAAAAB,会解释错误 ,再接到BBBB10AAAAABBBBB,也解释错误的情况。这就是TCP的粘包

       在网络传输应用中,通常需要在网络协议之上再自定义一个协议封装一下,简单做法就是在要发送的数据前面再加一个自定义的包头,包头中可以包含数据长度和其它一些信息,接收的时候先收包头,再根据包头中描述的数据长度来接收后面的数据。详细做法是:先接收包头,在包头里指定包体长度来接收。设置包头包尾的检查位(如群空间0x2开头,0x3结束来检查一个包是否完整)。对于TCP来说:1)不存在丢包,错包,所以不会出现数据出错 2)如果包头检测错误,即为非法或者请求,直接重置即可

       为了避免粘包现象,可采取以下几种措施。

        一是对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据立即传送的操作指令pushTCP软件收到该操作指令后,就立即将本段数据发送出去,而不必等待发送缓冲区满;

        二是对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;

         三是由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这种手段来避免粘包。

问题11.图解TCP的3次握手建立连接,4次握手释放连接?

         TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP传输连接的建立和释放是每一次面向连接的通信中必不可少的过程。因此,传输连接就由三个阶段,即:连接建立、数据传送和连接释放。

 

      这里的SYN=SYNchronizationSYN=1,ACK=0,表示连接请求报文段;同意建立连接则SYN=1ACK=1,连接后所有的ACK=1

三次握手(three-way handshake)方案解决了由于网络层会丢失、存储和重复分组带来的问题。试想不进行三次握手可能出现的问题?

 

      

        如上图所示,如果仅仅是2次握手的话,可能出现的问题如下:

       Host A发送的数据包由于网络的原因,出现了滞留,即延时到达了HostB。此时,B以为HostA发来了请求,于是就向HostA发送确认报文,以建立连接。而HostA收到报文后,由于其没有向HostB发起建立连接的请求,因此不会理睬HostB的确认,也不会向HostB发送数据。而此时的B认为已经建立起连接了,就等待HostA发送的数据,导致HostB的资源白白浪费!

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/3585633.html

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

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

相关文章

关机与禁止关机代码

今天抽空,写完了定时关机程序的代码,测试了一下,还不错,以前写过个禁止关机的程序,用来测试一下,看哪个强,先运行禁止关机的程序,用Windows xp的关闭计算机试了一下,关不了. 代码很少: private procedure QueryEndSession(var Msg:TMessage);Message WM_QueryEndSession;…

pythonweb开发面试_Python web 面试题(一)

1、列举django的内置组件? url 、view、model、template、中间件 2、列举django中间件的5个方法?以及django中间件的应用场景? process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) proce…

第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波18 - 低通、高通、带阻和带通滤波器、组合使用空间增强方法

低通、高通、带阻和带通滤波器 得到空间滤波器的第三种方法,生成一维滤波器函数,然后要么使用式(3.42)wvvTw vv^TwvvT生成二维可分离的滤波器函数,要么旋转这些一维函数来生成二维核。旋转后的一维函数是圆对称(各向同性&#x…

MySQL两千万数据优化迁移

最近有一张2000W条记录的数据表需要优化和迁移。2000W数据对于MySQL来说很尴尬,因为合理的创建索引速度还是挺快的,再怎么优化速度也得不到多大提升。不过这些数据有大量的冗余字段和错误信息,极不方便做统计和分析。所以我需要创建一张新表&…

Linux Tomcat 6.0安装配置实践总结

系统环境: Red Hat Enterprise Linux Server release 5.7 (Tikanga) 64位 Tomcat下载 从官方网站 http://tomcat.apache.org/下载你需要的Tomcat版本,目前Tomcat主要版本有Tomcat 6.0、Tomcat 7.0、Tomcat 8.0三个版本,下面我们以6.0(6.0.39…

如何给FormPanel表单中的元素赋值以及获取表单元素值

1.定义表单元素的name属性如下 var HLV new Ext.form.TextField({fieldLabel: 汇率,name:EXCHANGERATE,anchor: 30%}); 2.定义数据源 var ExchangeRatestore new Ext.data.Store({proxy: new Ext.data.HttpProxy({ url: WsECOTAX01.asmx/SelectExchangeRate, method: "po…

第4章 Python 数字图像处理(DIP) - 频率域滤波1 - 傅里叶级数和变换简史

本章主要讲解频域域滤波的技术,主要技术用到是大家熟悉的傅里叶变换与傅里叶反变换。这里有比较多的篇幅讲解的傅里叶的推导进程,用到Numpy傅里叶变换。本章理论基础比较多,需要更多的耐心来阅读,有发现有错误,可以与我…

python中str是什么函数_python str函数怎么用

展开全部 是将一个2113对象转成字符串显示5261,注意只是显示用,有些对象4102转成字符串没有直1653接的意思。 str():将变量转化为字符串类型 a 1 b [1, 2, 3] str_a str(a) print(a) print(type(a)) str_b str(b) print(b) print(type(b)) The str()…

[ofbiz]less-than (lt;) and greater-than (gt;) symbols

问题描述&#xff1a; In field [updateItemStr] less-than (<) and greater-than (>) symbols are not allowed 此处的field [updateItemStr]是services的一个IN参数&#xff0c;错误描述的意思是"<,>"不能出现在这个域内。 解决办法&#xff1a; 在ser…

分页探究--Filter+JSTL

最近卡了一个功能就是分页&#xff0c;查了很多资料&#xff0c;分页大概是两种类型&#xff1a;一种是把数据库的东西全部查出来然后放在session里&#xff0c;用list一页一页传到页面&#xff0c;这样的消耗比较大;另一种就是使用sql语句的limit来进行数据库分页查询。我使用…

iPhone开发资料之内存管理 ,循环引用导致的内存问题

iPhone开发资料之内存管理 ,循环引用导致的内存问题 https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447 http://en.wikipedia.org/wiki/Reference_counting 【IT168 技术文档】开…

python能做大型游戏吗_python有做大型游戏的潜力吗?

著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 岂止是有潜力&#xff0c;简直是很合适&#xff01; 猪厂两大游戏客户端引擎&#xff0c;NeoX 和 Messiah&#xff0c;都使用 Python 作为脚本语言。 你最近所了解的比较火的挂着猪厂旗号的&a…

第4章 Python 数字图像处理(DIP) - 频率域滤波2 - 复数、傅里叶级数、连续单变量函数的傅里叶变换、卷积

目录基本概念复数傅里叶级数冲激函数及其取样&#xff08;筛选&#xff09;性质连续单变量函数的傅里叶变换卷积基本概念 复数 复数CCC的定义为 CRjI(4.3)C R jI \tag{4.3}CRjI(4.3) R,IR,IR,I为实数&#xff0c;RRR是实部&#xff0c;III是虚部&#xff0c;j−1j \sqrt{-…

不要迷失在技术的海洋中【转】

转自http://www.cnblogs.com/lovecherry/archive/2007/10/28/940555.html 不要迷失在技术的海洋中 技术就好像一片汪洋大海&#xff0c;越深入越望不到边际。就拿自己的体验来说吧&#xff0c;2000年的时候在学校搞ASP&#xff0c;觉得网页开发就是这么简单&#xff0c;把数据库…

使用代码设置Item级的权限(权限总结1)

itle in english:set Item Level Permission for SharePoint (MOSS/WSS) List/Document Library Programmatically 有些时候&#xff0c;我们需要为文档库里面某个文件设置特殊的权限&#xff0c;这个权限不继承自列表权限&#xff0c;当然最简单的最好是再创建一个列表&#…

echarts 4.0.4怎么下载_怎么让ECharts的提示框tooltip自动轮播?

1. 怎么让ECharts的提示框tooltip自动轮播?在用ECharts做大屏或者可视化展示项目的时候&#xff0c;让提示框tooltip自动轮播是比较常见的需求&#xff0c;给大家推荐一个插件叫echarts-tooltip-auto-show,名字是有点长&#xff0c;但是挺好用的。在hover显示tooltip之后&…

[React Native]高度自增长的TextInput组件

之前我们学习了从零学React Native之11 TextInput了解了TextInput相关的属性。 在开发中,我们有时候有这样的需求, 希望输入区域的高度随着输入内容的长度而增长, 如下&#xff1a; 这时候我们需要自定义一个组件&#xff1a; 在项目中创建AutoExpandingTextInput.js import …

网站开启Gzip压缩-apache

找到并打开apache/conf目录中的httpd.conf文件 httpd.conf中打开deflate_Module和headers_Module模块&#xff0c;具体做法为将 如下两句前面的#去掉&#xff1a;LoadModule deflate_module modules/mod_deflate.so LoadModule headers_module modules/mod_headers.so 3.配置文…

第4章 Python 数字图像处理(DIP) - 频率域滤波3 - 取样和取样函数的傅里叶变换、混叠

目录取样和取样函数的傅里叶变换取样取样后的函数的傅里叶变换取样定理混叠由取样后的数据重建&#xff08;复原&#xff09;函数取样和取样函数的傅里叶变换 取样 fˉ(t)f(t)sΔT(t)∑n−∞∞f(t)δ(t−nΔT)(4.27)\bar f(t) f(t)s_{\Delta T}(t) \sum_{n-\infty}^{\infty}…

[转]Android开发,实现可多选的图片ListView,便于批量操作

本文转自&#xff1a;http://www.cnblogs.com/gergulo/archive/2011/06/14/2080629.html 之前项目需要实现一个可多选的图片列表&#xff0c;用户选中一到多张图片后&#xff0c;批量上传。但是网上有可多选普通列表的代码、也有单纯图片列表的代码&#xff0c;却没有两者合并的…