1、传输层存在的必要性
因为网络层的分组传输是不可靠的,无法了解数据到达终点的时间,无法了解数据未达终点的状态。因此有必要增强网络层提供服务的服务质量。
2、引入传输层的原因
面向连接的传输服务与面向连接的网络服务类似,都分为建立连接、传输数据、释放连接三个阶段;编址、寻址、流控制也是类似的。无连接的传输服务与无连接的网络服务也非常类似。一个非常显然的问题:既然传输层的服务与网络层的服务如此相似,那么为什么我们还要两个独立的层呢?
原因在于:传输层的代码全然执行在用户的机器上,可是网络层主要执行在由承运商控制的路由器上。试想下面几种情况?
① 网络层提供的服务不够用;
② 频繁的丢失分组;
③ 路由器时常崩溃。
用户在网络层上并没有真正的控制权,所以他们不可能用最好的路由器或者在数据链路层上用更好的错误处理机制来解决服务太差的问题。唯一的可能是在网络层之上的还有一层中提高服务质量。这就是传输层存在的必要性。
传输层的重要性:不不过另外一层,它是整个协议层次的核心所在。假设没有传输层,那么分层协议的整个概念将变得没有意义。
传输层的任务:在源机器和目标机器之间提供可靠的、性价比合理的传输数据服务,而且与当前使用的物理网络全然独立。
3、传输层的功能
数据传送,不关心数据含义,进程间通信。
弥补高层(上3层)要求与网络层(基于下3层)数据传送服务质量间的差异(差错率、差错恢复能力、吞吐率、延时、费用等),对高层屏蔽网络层的服务的差异,提供稳定和一致的界面。
4、传输层协议与网络层协议的主要差别
网络层(IP层)提供点到点的连接即提供主机之间的逻辑通信,传输层提供端到端的连接——提供进程之间的逻辑通信。
5、传输层的用途
传输层将数据分段,并进行必要的控制,以便将这些片段重组成各种通信流。在此过程中,传输层主要负责:
① 跟踪源主机和目的主机上应用程序间的每次通信;
② 将数据分段,并管理每一个片段;
③ 将分段数据重组为应用程序数据流;
④ 标识不同的应用程序。
6、port号的概念
执行在计算机中的进程是用进程标识符来标志的。执行在应用层的各种应用进程却不应当让计算机操作系统指派它的进程标识符。这是由于在因特网上使用的计算机的操作系统种类非常多,而不同的操作系统又使用不同格式的进程标识符。为了使执行不同操作系统的计算机的应用进程可以互相通信,就必须用统一的方法对TCP/IP体系的应用进程进行标志。
解决问题的方法就是在运输层使用协议端口号(protocol port number),或通常简称为端口(port)。
尽管通信的终点是应用进程,但我们能够把port想象是通信的终点,由于我们仅仅要把要传送的报文交到目的主机的某一个合适的目的port,剩下的工作(即最后交付目的进程)就由 TCP来完毕。
7、传输层的主要协议
TCP/ IP传输层的两个主要协议都是因特网的重要标准,传输控制协议TCP(Transmission Control Protocol)[RFC
768]、用户数据报协议UDP(User Datagram Protocol)[RFC 793]。
传输层的数据流要在网络端点之间建立逻辑连接。假设使用UDP,传输层的首要任务是将数据从源设备传输到目的设备。假设使用TCP,传输层主要通过滑动窗体来提供端到端控制,以及利用确认序列号和确认信息提供可靠性。传输层定义主机应用程序之间端到端的连接。
8、TCP&UDP的比較
TCP(Transmission Control Protocol)可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;电子邮件、文件传输程序。
UDP(User Datagram Protocol)不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
问题1:什么是面向连接、面向无连接?
面向连接举例:两个人之间通过电话进行通信。
面向无连接举例:邮政服务,用户把信函放在邮件中期待邮政处理流程来传递邮政包裹。显然,不可达代表不可靠。
从程序实现的角度解析面向连接、面向无连接例如以下:
TCP面向连接,UDP面向无连接(在默认的堵塞模式下):
在TCP协议中,当client退出程序或断开连接时,TCP协议的recv函数会马上返回不再堵塞,由于服务端自己知道client已经退出或断开连接,证明它是面向连接的;
而在UDP协议中,recvfrom这个接收函数将会始终保持堵塞,由于服务端自己不知道client已经退出或断开连接,证明它是面向无连接的)。
从上图也能清晰的看出,TCP通信须要server端侦听listen、接收client连接请求accept,等待clientconnect建立连接后才干进行数据包的收发(recv/send)工作。
而UDP则server和client的概念不明显,server端即接收端须要绑定port,等待client的数据的到来。兴许便能够进行数据的收发(recvfrom/sendto)工作。
问题2:什么是面向字节流、面向报文?
面向字节流:尽管应用程序和TCP的交互是一次一个数据块(大小不等),但TCP把应用程序看成是一连串的无结构的字节流。TCP有一个缓冲,当应用程序传送的数据块太长,TCP就能够把它划分短一些再传送。假设应用程序一次仅仅发送一个字节,TCP也能够等待积累有足够多的字节后再构成报文段发送出去。
面向报文:面向报文的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。因此,应用程序必须选择合适大小的报文。若报文太长,则IP层须要分片,减少效率。若太短,会是IP太小。(谢希仁,第五版。UDP相应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。这也就是说,应用层交给UDP多长的报文,UDP就照样发送),即一次发送一个报文)。
问题3:在默认的堵塞模式下,为什么说TCP无边界,UDP有边界?
对于TCP协议,client连续发送数据,仅仅要服务端的这个函数的缓冲区足够大,会一次性接收过来,即client是分好几次发过来,是有边界的,而服务端却一次性接收过来,所以证明是无边界的;
而对于UDP协议,client连续发送数据,即使服务端的这个函数的缓冲区足够大,也仅仅会一次一次的接收,发送多少次接收多少次,即client分几次发送过来,服务端就必须按几次接收,从而证明,这样的UDP的通讯模式是有边界的。
问题4:UDP 怎样发送大量的数据?怎样处理分包?
用 updclient 一次不能发送太大的数据量,不然就会报错:一个在数据报套接字上发送的消息大于内部消息缓冲器或其它一些网络限制,或该用户用于接收数据报的缓冲器比数据报小。但不知道一次究竟能发多少字节?假设把一个大的字节数组拆分成若干个字节数组发送,那么接收时怎样推断和处理呢?
答:方法非常easy:
1、在client将你要发送的内容(文件什么的都能够)分块,每块内容进行编号,然后发送;
2、服务端在接收到你的分块数据以后,依据你的client数据内容的编号又一次组装;
3、一般我们在发送数据的时候,尽量採用比較小的数据块的方式(我的都没有超过1024的),数据块太大的话easy出现发送和接收的数据时间长,匹配出问题。
问题5.UDP发包的问题
问:udp发送两次数据,第一次 100字节,第二次200字节,接包方一次recvfrom(
1000 ),收到是 100,还是200,还是300?
答:UDP是数据报文协议,是以数据包方式,所以每次能够接收100,200,在理想情况下,第一次是不管recvfrom多少都是接收到100。当然,可能因为网络原因,第二个包先到的话,有可能是200了。对可能会因为网络原因乱序,所以可能先收到200,所以自己定义的udp协议包头里都要加上一个序列号,标识发送与收包相应。
问题6.TCP的发包问题
问:相同假设换成tcp,第一次发送 100字节,第二次发送200字节,recv(
1000 )会接收到多少?
答:tcp是流协议,所以recv( 1000 ),会收到300 tcp自己处理好了重传,保证数据包的完整性
问题7.有分片的情况下例如以下处理
问:假设MTU是1500,使用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.不同连接到同一个port的包处理
问:TCP
A -> C发100
B -> C发200
AB同一时候同一port
C recv(1000) ,会收到多少?
答:A与C是一个tcp连接,B与C又是还有一个tcp连接,所以不同socket,所以分开处理。每一个socket有自己的接收缓冲和发送缓冲
问题10.什么是TCP粘包
在应用开发过程中,基于TCP网络传输的应用程序有时会出现粘包现象(即发送方发送的若干包数据到接收方接收时粘成一包)。详解例如以下:因为TCP是流协议,对于一个socket的包,如发送 10AAAAABBBBB两次,因为网络原因第一次又分成两次发送, 10AAAAAB和BBBB,假设接包的时候先读取10(包长度)再读入兴许数据,当接收得快,发送的慢时,就会出现先接收了 10AAAAAB,会解释错误 ,再接到BBBB10AAAAABBBBB,也解释错误的情况。这就是TCP的粘包。
在网络传输应用中,通常须要在网络协议之上再自己定义一个协议封装一下,简单做法就是在要发送的数据前面再加一个自己定义的包头,包头中能够包括数据长度和其他一些信息,接收的时候先收包头,再依据包头中描写叙述的数据长度来接收后面的数据。具体做法是:先接收包头,在包头里指定)不存在丢包,错包,所以不会出现数据出错 2)假设包头检測错误,即为非法或者请求,直接重置就可以
为了避免粘包现象,可採取下面几种措施。
一是对于发送方引起的粘包现象,用户可通过编程设置来避免,TCP提供了强制数据马上传送的操作指令push,TCP软件收到该操作指令后,就马上将本段数据发送出去,而不必等待发送缓冲区满;
二是对于接收方引起的粘包,则可通过优化程序设计、精简接收进程工作量、提高接收进程优先级等措施,使其及时接收数据,从而尽量避免出现粘包现象;
三是由接收方控制,将一包数据按结构字段,人为控制分多次接收,然后合并,通过这样的手段来避免粘包。
问题11.图解TCP的3次握手建立连接,4次握手释放连接?
TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP传输连接的建立和释放是每一次面向连接的通信中不可缺少的过程。因此,传输连接就由三个阶段,即:连接建立、数据传送和连接释放。
这里的SYN=SYNchronization,SYN=1,ACK=0,表示连接请求报文段;允许建立连接则SYN=1,ACK=1,连接后全部的ACK=1。
三次握手(three-way handshake)方案攻克了因为网络层会丢失、存储和反复分组带来的问题。试想不进行三次握手可能出现的问题?
如上图所看到的,假设不过2次握手的话,可能出现的问题例如以下:
Host A发送的数据包因为网络的原因,出现了滞留,即延时到达了HostB。此时,B以为HostA发来了请求,于是就向HostA发送确认报文,以建立连接。而HostA收到报文后,因为其没有向HostB发起建立连接的请求,因此不会理睬HostB的确认,也不会向HostB发送数据。而此时的B觉得已经建立起连接了,就等待HostA发送的数据,导致HostB的资源白白浪费!
连接释放:
——部分内容參考了《计算机网络》、网上查找内容。