1.参考模型
注:不同层次由分离的代码实现,不同次的代码之间通过明确定义的接口来交换数据或转发命令。
2.TCP的socket和buffer
(1)接收
每个TCP socket在内核中都有1个发送缓冲区和1个接收缓冲区,TCP的全双工的工作模式以及TCP的流量(拥塞)控制依赖于这两个独立的buffer和buffer的填充状态。
接收缓冲区把数据缓存,如果应用层没有调用recv( )读取,数据会一直缓存在对应socket的接收缓冲区。如果接收缓冲区满,收端就通知发端,接收窗口关闭(win=0),这就是滑动窗口,保证了接收缓冲区不会溢出。recv( )就是把接收缓冲区的数据拷贝到应用层。
(2)发送
应用层调用send( )发送数据,就是把数据从应用层拷贝到发送缓冲区后就返回,实际上数据还没有发送到接收端。
3.滑动窗口
TCP连接建立时,接收端的初始滑动窗口大小如下图所示:
收端通过ACK来通知发端自己的滑动窗口大小,而发端发送数据长度就根据接收端的滑动窗口大小来确定,发端不会发送超过接收端接收能力的数据流,这样就起到了流量控制的作用。
4.以太网帧数据结构
通信过程中,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示:
不同的协议层对数据包的称谓不同,传输层叫段(segment),网络层叫数据报(datagram),链路层叫帧(frame)。数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。
①集线器(Hub)是工作在物理层的网络设备,用于双绞线的连接和信号中继(将已衰减的信号再次放大使之传得更远)。
②交换机是工作在链路层的网络设备,可以在不同的链路层网络之间转发数据帧,由于不同链路层的帧格式不同,交换机需要将进来的数据包拆掉链路层首部重新封装后再转发。
③路由器是工作在第三层的网络设备,同时兼有交换机的功能,可以在不同的链路层接口之间转发数据包,因此路由器需要将进来的数据包拆掉网络层和链路层两层首部并重新封装。
④网络层的IP协议是构成Internet的基础。IP协议不保证传输的可靠性,数据包在传输过程中可能丢失,可靠性可以在上层协议或应用程序中提供支持。
⑤数据传输经过的各层协议过程如下图所示:
以太网驱动程序首先根据以太网首部中的“上层协议”字段确定该数据帧的有效载荷(payload,指除去协议首部之外实际传输的数据)是IP、ARP 还是RARP 协议的数据报,然后交给相应的协议处理。
假如是IP 数据报,IP 协议再根据IP 首部中的“上层协议”字段确定该数据报的有效载荷是TCP、UDP、ICMP 还是IGMP,然后交给相应的协议处理。
假如是TCP 段或UDP段,TCP 或UDP 协议再根据TCP 首部或UDP 首部的“端口号”字段确定应该将应用层数据交给哪个用户进程。
IP 地址是标识网络中不同主机的地址,而端口号就是同一台主机上标识不同进程的地址,IP 地址和端口号合起来标识网络中唯一的进程。
虽然IP、ARP 和RARP 数据报都需要以太网驱动程序来封装成帧,但是从功能上划分,ARP 和RARP 属于链路层,IP 属于网络层。虽然ICMP、IGMP、TCP、UDP 的数据都需要IP 协议来封装成数据报,但是从功能上划分,ICMP、IGMP 与IP 同属于网络层,TCP 和UDP属于传输层。
(1)以太网帧格式
①其中的源地址和目的地址是指网卡的硬件地址(也叫MAC 地址),长度是48 位,是在网卡出厂时固化的。
②注意网卡芯片(例如DM9000A)收到的数据就是如上所示的一长串数据;其中包括以太网帧头、IP报报头、传输层协议段头、应用层所需数据。
③以太网帧中的数据长度规定最小46 字节,最大1500 字节,ARP 和RARP 数据包的长度不够46 字节,要在后面补填充位。最大值1500 称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU,如果一个数据包从以太网路由到拨号链路上,数据包度大于拨号链路的MTU了,则需要对数据包进行分片fragmentation)。ifconfig 命令的输出中也有“MTU:1500”。注意,MTU 个概念指数据帧中有效载荷的最大长度,不包括帧首部的长度。
(2)Mac首部
(3)IP报头格式
IP 数据报的首部长度和数据长度都是可变长的,但总是4 字节的整数倍。普通的IP首部长为20个字节,除非含有选项字段。
①4位版本:目前协议版本号是4,即IPV4。
②4位首部长度:数值是以4 字节为单位的,最小值为5,也就是说首部长度最小是4x5=20 字节,也就是不带任何选项的IP 首部,4 位能表示的最大值是15,也就是说首部长度最大是60 字。(0x45&0x0f)×4bytes=20bytes。
③服务类型(TOS):服务类型字段包括一个3bit的优先权字段(现在已经被忽略),4bit的TOS子字段和1bit未用位必须置0。4bit的TOS分别代表:最小时延,最大吞吐量,最高可靠性和最小费用。4bit中只能置其中1比特。如果所有4bit均为0,那么就意味着是一般服务。
④总长度:总长度字段是指整个IP数据报的长度,以字节为单位。利用首部长度和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16bit,所以IP数据报最长可达65535字节。当数据报被分片时,该字段的值也随着变化。
⑤标识字段:标识字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1,可用于分片和重新组装数据报。
⑥3 位标志和13 位片偏移用于分片。
⑦生存时间:TTL(time-to-live)生存时间字段设置了数据报可以经过的最多路由器数。它指定了数据报的生存时间。TTL的初始值由源主机设置(通常为 3 2或6 4),一旦经过一个处理它的路由器,它的值就减去 1。当该字段的值为 0时,就表示路由已经太长了仍然找不到目的主机的网络,数据报就被丢弃,并发送ICMP报文通知源主机,因此这个生存时间的单位不是秒,而是跳(hop)。
⑧协议字段指示上层协议是TCP、UDP、ICMP 还是IGMP。
⑨首部检验和:首部检验和字段是根据 I P首部计算的检验和码。它不对首部后面的数据进行计算。ICMP、
IGMP、UDP和TCP在它们各自的首部中均含有同时覆盖首部和数据检验和码。
⑩IPv4的IP 地址长度为32 位。
(4)TCP首部格式
①源端口号和目的端口号:用于寻找发端和收端应用进程。这两个值加上I P首部中的源端I P地址和目的端I P地址唯一确定一个T C P连接。
②序号字段:序号用来标识从TCP发端向TCP收端发送的数据字节流,它表示在这个报文段中的的第1个数据字节。如果将字节流看作在两个应用程序间的单向流动,则TCP用序号对每个字节进行计数。序号是32 bit的无符号数,序号到达 232-1后又从0开始。
当建立一个新的连接时,SYN标志变1。序号字段包含由这个主机选择的该连接的初始序号ISN(Initial
Sequence
Number)。该主机要发送数据的第一个字节序号为这个ISN加1,因为SYN标志消耗了一个序号(将在下章详细介绍如何建立和终止连接,届时我们将看到
F I N标志也要占用一个序号)
③确认序号:既然每个传输的字节都被计数,确认序号包含发送确认的一端所期望收到的下一个序号。因此,确认序号应当是上次已成功收到数据字节序号加
1。只有ACK标志(下面介绍)为 1时确认序号字段才有效。发送ACK无需任何代价,因为 32 bit的确认序号字段和A C K标志一样,总是T
C P首部的一
部分。因此,我们看到一旦一个连接建立起来,这个字段总是被设置, ACK标志也总是被设置为1。TCP为应用层提供全双工服务。这意味数据能在两个方向上独立地进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。
④首部长度:首部长度给出首部中 32 bit字的数目。需要这个值是因为任选字段的长度是可变的。这个字段占4 bit,因此TCP最多有60字节的首部。然而,没有任选字段,正常的长度是 2 0字节。
⑤标志字段:在T C P首部中有 6个标志比特。它们中的多个可同时被设置为1.
URG紧急指针(u rgent pointer)有效。
ACK确认序号有效。
PSH接收方应该尽快将这个报文段交给应用层。
RST重建连接。
SYN同步序号用来发起一个连接。
FIN发端完成发送任务。
⑥窗口大小:TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16 bit字段,因而窗口大小最大为 65535字节。
⑦检验和:检验和覆盖了整个的 TCP报文段:TCP首部和TCP数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。
⑧紧急指针:只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。 T C P的紧急方式是发送端向另一端发送紧急数据的一种方式。
⑨选项:最常见的可选字段是最长报文大小,又称为 MSS (Maximum Segment Size)。每个连接方通常都在通信的第一个报文段(为建立连接而设置 S Y N标志的那个段)中指明这个选项。它指明本端所能接收的最大长度的报文段。
(5)UDP首部
①端口号:用来表示发送和接受进程。由于 I P层已经把I P数据报分配给T C P或U D P(根据I P首部中协议字段值),因此T C P端口号由T C P来查看,而 U D P端口号由UDP来查看。T C P端口号与UDP端口号是相互独立的。
②长度:UDP长度字段指的是UDP首部和UDP数据的字节长度。该字段的最小值为 8字节(发送一份0字节的UDP数据报是 O K)。
③检验和:UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。