第二章传输层、TCP、UDP、和SCTP
UDP是一个简单的、不可靠的传输协议,而TCP是一个复杂、可靠的字节流协议。
协议族介绍: 互联网协议族(英语:Internet Protocol Suite,缩写为IPS),是一个网络通讯模型,以及一整个网络传输协议家族,为互联网的基础通讯架构。它常被通称为TCP/IP协议族(英语:TCP/IP Protocol Suite,或TCP/IP Protocols),简称TCP/IP。因为这个协议家族的两个核心协议,包括TCP(传输控制协议)和IP(网际协议),为这个家族中最早通过的标准。由于在网络通讯协议普遍采用分层的结构,当多个层次的协议共同工作时,类似计算机科学中的堆栈,因此又被称为TCP/IP协议栈(英语:TCP/IP Protocol Stack) 。这些协议最早发源于美国国防部(缩写为DoD)的ARPA网项目,因此也被称作DoD模型(DoD Model)。这个协议套组由互联网工程任务组负责维护。 [1]
ICMP 含义:
ICMP是(Internet Control Message Protocol)Internet控制报文协议。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。
unix协议框架简介(可通过英文全称记忆):
IPV4:网际协议版本4.自从二十世纪八十年代早期以来一直是网际协议族的主力协议。使用32位地址。IPV4给TCP、UDP、SCTP、ICMP、IGMP提供分组递送服务
IPV6协议:网际协议版本6,20世纪90年代中期作为IPV4的替代品,主要变化是使用了128位更大的地址,应对20世纪90年代以来互联网的爆发增长
TCP:传输控制协议。TCP是一个面向连接的协议,为用户提供全双工的字节流。TCP是一种流套接字。TCP关心确认、超时和重传之类的细节。TCP既可以使用IPV4,也可以使用IPV6
UDP:用户数据报文协议。UDP是一个无连接协议,UDP是一种数据包套接字。UDP不能保证数据到达目的地,与TCP一样既可以使用IPV4 也 可以使用IPV6
SCTP:流控制传输协议。SCTP提供一个可靠的全双工的面向连接的协议,我们使用关联一次来指称SCTP中的连接,因为SCTP是多宿主的,从而每个关联的两端均涉及一组地址和一个端口号。SCTP提供消息服务,也就维护来自应用层的记录边界。与TCP和UDP 一样,SCTP既可以使用IPV4,又可以使用IPV6
ICMP:网际控制消息协议。ICMP处理在路由器和主机之间流通的错误和控制消息。这些消息通常由TCP\IP网络支持软件本身(而不是用户进程)产生和处理的。用ping和traceroute程序可以同样使用ICMP。有时我们称这个协议为ICMPV4,以便与ICMPV6区别
IGMP:网际组管理协议,多用于广播
ARP:地址解析协议。ARP把一个IPV4地址映射成一个硬件地址。ARP通常用于诸如以太网、令牌环网和FDDI等广播网络,在点到点的网络兵不需要
RARP:反向地址解析协议。RARP把一个硬件地址解析成一个IPV4地址。他有时用于一个无盘节点的引导。
ICMPv6:网际控制消息协议版本6,综合了ICMPv4、TGMP和ARP的功能
BPF:BSD分组过滤器。该接口提供与数据链路层的访问能力,通常可以在院子Berkeley的内核中找到
DLPI:数据链路提供者接口。该接口也提供对于数据链路层的访问能力,通常随SVR4内核提供
所有网际协议遵循RFC的正式规范
TCP先于某个给定的服务器建立连接,再跨连接与服务器建立数据交换,最后终止连接
TCP再数据发送失败后,可以持续4~10分中的重传
TCP服务端在接收到客户端发送过来的数据后,会根据客户端发来的先后顺序排列,如果由于网络拥堵发送来的重复数据,TCP服务端将会抛弃这些重复数据
TCP提供了可靠的流量控制,TCP总是会告诉对端一次能接收多少数据 以及缓冲区剩余大小,当缓冲区满了以后,服务端必须从缓冲区读取数据时,方能再从对端接收数据
TCP是一种全双工的协议
SCTP与tcp 不同是多宿主的,而且发送消息是一个模块一个模块的面向消息和面向连接的协议
三路握手
1)TCP准备好接收外来的连接,通过socket listen bind 等函数
2)客户端通过connect 建立连接,发送一个SYN序列号
3)服务器必须确认(ACK)客户的SYN,然后在发送一个SYN的分节
4)客户端确认服务器的SYN
每一个SYN的ACK确认号就是SYN加1
每一个FIN的确认号就是FIN加1
TCP选项
TCP选项:
MSS选项(maximum segment size)即MSS,通告对端它的最大分节大小,参数TCP_MAXSEG可以设置这个TCP选项
窗口规模选项:通告对端最大窗口规模是65535,可以通过SO_RCVBUF套接字选项来影响这个选项
时间戳选项。
TCP连接终止(四路握手)
1)某个应用程序首先调用close,我们称该端执行主动关闭。该端的TCP于是发送一个FIN分节,表示数据发送完毕
2)接收到这个FIN的对端执行被动关闭,FIN的接收意味着相应的连接上再无数据接收
3)TCP也会发送一个FIN
4)接收到这个最终FIN的原发送端确认这个FIN
类似SYN,一个FIN也占据一个字节的空间,每个FIN的ACK号就是FIN的序列号加1
TCP连接状态
TCP 为一个连接定义了11种状态
一方发送SYN 则他的状态是SYNSENT,收到一段并且发送ACK+1的状态则变为SYNRCVD,如过在发送ACK被确认则变为ESTABLISHED
如果某个应用程序在接收到一个FIN之前调用close,就会转换为 FINWAIT1状态。但如果某个应用程序在ESTABLISHED状态期间接收到一个FIN,那就转换为一个CLOSE WAIT状态
主动关闭发送FIN,状态会变为FINWAIT1
接收端接收到FIN 会变为 CLOSEWAIT 对端比为了FINWAIT_2
然后发送ACK确认码和FIN会变为LASTACK 对端变为了LASTACK
发送端再次发送ACK码,这时对端会变为CLOSED状态
TIME_WAIT状态
TIME_WAIT实在路由异常发生迷途时,花费一定时间找寻另一条路的一个状态体现,该断点停留的时间一般是2MSL(maximum segment lifetime)
TIME_WAIT存在的理由:
1)可靠的实现TCP的全双工
close 的主动端很可能会出现TIME_WAIT状态,因为他必须重传ACK到另一端,以确保数据的可靠性
2)允许重复分节在网络中消逝
同一个ip和端口被重复绑定的时候,保证先前的重复分组都在网络中消逝
建立连接(四路握手)
1)建立连接通过socket,bind和listen这三个函数来完成
2)客户端调用connect关联消息进行一个隐式的主动打开。这使得用户sctp发送一个INIT的消息,这个消息告诉服务器客户的ip和初始序列号、用于标识关联中所有分组的初始标记,客户请求外出流的数目以及客户能支持外来流的数目。
3)服务器以一个INIT ACK码确认客户的INIT消息,其中含有服务器的ip地址清单、初始序列号、起始标记、服务器请求的外出流数目 服务器能支持的外来流数目,以及一个状态cookie。状态cookie 包含服务器用于确信本关联有效所需要的所有状态,他是数字化签名的确保他的有效性
4)客户用一个COOKIE ECHO回射服务器的状态cookie,处理cookie echo外,该消息可能在同一分组中还捆绑了用户数据
5)服务器用一个COOKIE ACK消息确认客户回射的cookie是正确的
关联终止
SCTP 不允许半关闭,当一端关闭某一个关联,另一端必须要停止数据发送
SCTP 没有TIME_WAIT状态
(由于SCTP在unix是一个比较新的协议,而且并没有大面积推开,所以就不在继续看了)
TCP、UDP和SCTP使用的是16位整数的端口号(1字节2个16进制)
服务端指定一个端口,客户端是一个临时端口
端口号的划分:
0~1023 这些端口由IANA控制,是系统保留端口
已登记端口为:1024~49151
49152~65535是动态的或私用端口,IANA并不管这些端口。他们是我们所谓的临时端口
在unix网络编程中通常的做法是主服务器通过循环派生一个子进程来处理每一个新的连接,如果一个子进程继续使用服务器众所周知的端口来服务一个长时间的请求将发生什么?服务器上所有目的端口为21的其他TCP分节都被传递送给拥有监听套机子的最初那个服务器(即最开始的父进程),然后派生一个个子进程来处理客户端请求。
IPV4数据报的最大大小是65535字节,包括IPV4首部
IPV6数据包最大大小是65575字节
当一个IP数据报将从某个接口送出时,如果大小超过相应的链路MTU,IPV4和IPV6将会执行分片
每一个TCP套接字有一个发送缓冲区,我们可以使用SO_SNDBUF来更改缓冲区的大小。当某个应用程序调用write的时候,内核从应用进程的缓冲区中复制所有数据到所写套接字的发送缓冲区。如果套接字的发送缓冲区容不下应用进程的所有数据(或者应用进程缓冲区大于发送进程的缓冲区,或是套接字缓冲区已经有其他数据),该应用进程将休眠,write直到应用进程所有数据都写到套接字缓冲区才会做返回。但是并不能代表对端已经接收到数据
tcp提取缓冲区的数据发送对端,对端tcp 必须确认收到的数据,对端ack到达后TCP才会丢去缓冲区中已经确认过的数据。TCP必须对已发送的一个数据保留副本,直到收到对方的确认
任何UDP套接字都有发送缓冲区的大小,我们可以使用SO_SNDBUF,他仅仅是修改了写到套接字数据报上的大小上限,如果一个进程写一个大于发送缓冲区大小的数据报,内核会返回一个EMSGSIZE的错误,UDP无需一个真正的发送缓冲区因为他本身就是不可靠的,通常被复制到某种格式的一个内核缓冲区中,数据被发送之后,这个副本会被链路层丢弃
如果udp write 成功返回表示所有数据已经被加入链路层输出列队,如果没有空间存放数据报货某个片段,内核通常会返回一个ENOBUFS错误给应用进程