TCP/IP是“transmission Control Protocol/Internet Protocol”的简写,中文译名为传输控制协议/互联网络协议。TCP/IP不是一个协议,而是一个协议簇的统称。它是当今互联网的基础,理解它对程序员很重要。
说起TCP/IP协议就不得不提OSI(Open System Interconnect),即开放式系统互联。说起TCP/IP与OSI之间的关系,一般都认为TCP/IP是简化的OSI模型。实质未然,首先TCP/IP开发时间早于OSI,其次OSI由于定义太详细没有被商用,相反TCP/IP由于定义简单(只有四层)被广泛采用。不过,理解OSI可以帮助我们更好的理解TCP/IP。
OSI参考模型有7层,TCP/IP模型包括4层,由于OSI参考模型的会话层、表示层、应用层与TCP/IP模型的应用层相对应,OSI参考模型的物理层、数据链路层与TCP/IP模型的网络接口层相对应,为了方便的理解原理,往往采取折中的办法,采用一种五层协议的原理体系结构,如下图所示
- 层与层之间关系
层与层之间互相调用,同层之间互相通信。越下面的层,越靠近硬件;越上面的层,越靠近用户。
- 层与协议
每一层都是完成一种功能。为了完成这些功能,就需要大家遵守共同的规则。大家遵守的规则就叫做协议(protocol);每一层都定义了许多协议,如TCP:传输控制协议、UDP:用户报文协议、telnet:远程登录协议、SMTP:简单邮件传输协议、FTP:文件传输协议、HTTP:超文本传输协议、DNS:域名系统等。
- TCP/IP通信的三次握手、四次挥手
首先说一下,TCP/IP标志位:
SYN(synchronous)同步标志
同步标志。该标志仅在三次握手简历TCP连接时有效。它提示TCP/IP连接的服务端检查序列编号,即同步序列编号。该序列编号为TCP/IP连接端(一般是客户端)的初始序列编号。在这里,可以把TCP/IP连接交换的数据看作为一个范围从0到4,294,967,295的32为计数器。通过TCP/IP连接交换的数据每一个字节都经过序列编号。在TCP/IP报文头中的序列表号栏包括了TCP分段中第一个字节的序列编号。
ACK(acknowledgement)确认标志
大多数情况下该标志位是之为的。TCP/IP报文头内确认编号栏内包含的确认编号(w+1,Figure-1)为下一个预期的序列编号,同时提示远端服务器已成功接受所有数据。
PSH(push)传送标志
该标志表示接收端不将该数据进行队列处理,而是尽可能快将数据转由应用处理。在处理telent或rlogin等交互模式的连接时,该标志总是置位的。
FIN(finish)结束标志
用来结束一个TCP/IP回话,但对应端口仍处于开放状态,准备接收后续数据。
RST(reset)重置标志
用于重置响应的TCP/IP连接
URG(urgent)紧急标志
紧急标志置位。
三次握手:
第一次握手:客户端发送SYN包(SYN=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=x+1),同时自己也发送SYN包(SYN=y),即SYN+ACk包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端与服务器端进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包不包含数据,三次握手完毕后,客户端与服务器端才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接前,TCP连接都将一直保存下去。
与建立连接的“三次握手”类似,断开一个TCP连接则需要“四次挥手”。
第一次挥手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发送数据了(当然,在FIN包之前发送出去的数据,如果没有收到对应的ACK确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可以接收数据。
第二次挥手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。
第三次挥手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
第四次挥手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
下面我们从下而上说一说每层的作用及协议。
1. 物理层
平常我们想上网会怎么办呢?肯定要先安装宽带然后拉根网线到你面前插上电脑或路由器上然后配置一下,这样你就可以上网了。像这样用光缆、电缆、双绞线、无线电波等方式把多个电脑连接起来的这就是“物理层”。它主要规定了网络的 一些电气特性,负责传送0和1的电信号。
2. 链接层
2.1 定义
如果只传送单纯的0和1的话是没有任何意义的,所以必须规定解读的方式:多少个电信号算一组?每个信号位有何意义?这就是“链接层”的功能,它在“物理层”的上方,确定了0和1的分组方式。
2.2 以太网协议
“以太网”(Ethernet)是当今现有局域网采用的最通用的通信协议标准。
“以太网”规定,一组电信号构成一个数据包,叫做“帧”(Frame)。每一帧分成两个部分:标头(Head)和数据(Data)。
“标头”包含数据包的一些说明,比如发送者、接受者、数据类型等;“数据”则是数据包的具体内容。
“标头”的长度,固定为18字节;“数据”的长度,最短为46字节,最长为1500字节。因此,整个“帧”最短为64字节,最长为1518字节。如果数据较长,那么就必须分割称多个帧进行发送。
2.3 MAC地址
上面提到的,“标头”包含了发送者和接受者的信息。那么,发送者和接受者是如何标识呢?
以太网规定,连入网络的所有设备,都必须具有“网卡”接口。数据包必须是从一块网卡,传送到另一块网卡。网卡的地址,就是数据报的发送地址和接收地址,这叫做MAC地址。每块网卡出厂的时候,都有一个全世界独一无二的MAC地址,长度是48个二进制位,通常用12个十六进制数表示。前6个十六进制数是厂商编号,后6个是该厂商的网卡流水号。
2.4 广播
有了MaC地址,就可以确定网卡和数据包的路径。那么一块网卡怎么会知道另一块网卡的MAC地址?答案是用ARP协议它是“网络层”的协议,后面会详细说明。
就算有了MAC地址,系统怎样才能把数据包准确送到接收方?答案是以太网采用了一种很“原始”的方式,它不是把数据包准确送到接收方,而是向本网络内所有计算机发送,让每台机器自己判断是否为接收方:如果自身的MAC地址和接收方MAC地址相同,就接收这个包,做进一步处理,否则就丢弃这个包。这种发送方式就叫做“广播”(broadcasting)。
有了数据包的定义、网卡的MAC地址、广播的发送方式,“链接层”就可以在多台计算机之间传输数据了。
3. 网络层
3.1 网络层的由来
以太网协议,依靠MAC地址发送数据。理论上,单单靠MAC地址就可以向全世界任何一台计算机发送数据,技术是可以实现的。但是这样做有一个重大的缺点。以太网采用广播方式发送数据包,所有成员人手一“包”,不仅效率低,而且局限在发送这所在子网络,也就是说,如果两台计算机不在同一个子网络,广播是传不过去的。但这种设计是合理的,否则互联网上的每一台计算机都会收到所有包,想想都觉得恐怖。
互联网是无数子网络共同组成的一个巨型网络。因此必须找到一种方法,能够区分哪些MAC地址属于同一个子网络,哪些不是。如果是同一个子网络,就采用广播方式传送,否则就采用“路由”的方式发送。遗憾的是,MAC地址本身无法做到这一点。它只与厂商有关,与所处网络无关。
这就导致了“网络层”的诞生。它的作用是引进一套新的地址,使得我们能够区分不同的计算机是否属于同一个子网络。这套地址就叫做“网络地址”,简称“网址”。于是“网络层”出现以后,每台计算机都有了两种地址,一种是MAC地址,另一种是网络地址。两种地址之间没有任何联系,MAC地址是绑定在网卡上的,网络地址则是管理员分配的,它们只是随机组合在一起。
网络地址帮助我们确定计算机所在的子网络,MAC地址则将数据包发送到该自网络中目标网卡。因此,从逻辑上可以判断,必定是优先处理网络地址,然后再处理MAC地址。
3.2 IP协议
规定网络地址的协议,叫做IP协议。由它所定义的地址,就被称为IP地址。
目前,广泛采用的IP协议是第四版,简称IPv4。它的下一个版本是IPv6。IPv6主要是解决IP地址不足的问题。这里主要说一下IPv4。
IPv4规定的网络地址由32个二进制数组组成。我们习惯用分成四段十进制数表示IP地址,数值范围从0.0.0.0到255.255.255.255之间。
互联网上的每台计算机都会分配一个IP地址.这个地址分成两个部分,前一部分代表网络,后一部分代表主机。比如,IP192.168.1.100,这是一个32位的地址,假定它的网络部分前24位(192.168.1),那么主机部分就后8位(最后的那个1)。处于一个子网络的电脑,它们的IP地址的网络部分必定相同,也就是说192.168.1.100与192.168.1.102处于同一个子网络。但这只是假设,单单从IP地址来判断网络部分是无法判断的。网络部分可以是前24位,16位,甚至是2位。
那怎样通过IP地址来判断两台计算机是否属于同意子网络呢?这就需要用到另一个参数“子网掩码”(subnet mask)。
“子网掩码”就是表示子网络特征的一个参数。它在形式上等于IP地址,也是一个32为二进制数字,它的网络部分全部为1,主机部分全部为0。比如,192.168.1.100这个IP地址,如果网络部分是前24为,主机部分为后8为的话,那么子网掩码为11111111.11111111.11111111.00000000,写成十进制就是255.255.255.0
知道了”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算(两个数位都是1则运算结果为1,否则为0),然后比较结果是否相同,如果相同则表明他们在同一子网络中,否则就不是。比如,一直192.168.1.100和192.168.1.101的子网掩码都是255.255.255.0,要想知道他们是否在同一子网络的话,需要与子网掩码进行AND运算,结果都是192.168.1.0,因此他们处于同一个子网络。
IP协议的作用主要有两个,一个是为每台计算机分配IP地址,另一个是确定哪些地址在同一个子网络。
3.3 IP数据包
根据IP协议发送的数据,就叫做IP数据包。它包含 IP地址的信息。
前面说过,以太网数据包只包含MAC地址,并没有IP地址的栏位。那么是否需要修改数据定义,再添加一个栏位呢?
答案是不需要的,我们可以把IP数据包直接放进以太网数据包的“数据”部分,因此完全不用修改以太网络的规格。这就是互联网分层结构的好处:上层的变动完全不涉及下层的结构
IP数据包的结构也分为“标头”和“数据”两部分。
“标头”部分主要包括版本、长度、IP地址等信息,“数据”部分则是IP数据包的具体内容。它放进以太网数据包后,以太网数据包就变成了下面这样。
IP数据包的“标头”部分长度为20到60字节,整个数据包的总长度最大为655,535字节。因此,理论上,一个IP数据包的“数据”部分,最长为65,515字节。前面说过,以太网数据包“数据”部分最长只有1500字节。因此,如果IP数据包超过1500字节,就需要切割成几个以太网数据包,分开发送了。
3.4 ARP协议
前面提到过ARP协议,在这里详细说一下。因为IP数据包是放在以太网数据包里发送的,所以我们必须直到两个地址,对方的MAC地址和IP地址。通常情况下,对方的IP地址是一直的,但是我们不知道它的MAC地址。所以我们需要一种机制,能够从IP地址得到MAC地址。
这里又分为两种情况。第一种情况,两台主机不再同一子网络,那么事实上没有办法得到对方的MAC地址,只有把数据把数据包传到两个子网络连接处的网关(gateway),让网关去处理。
第二种情况,两台主机在同一子网络,那么我们可以用ARP协议得到对方的MAC地址。ARP协议也是发出一个数据包(也包含在以太网数据包中)。其中包含它要查询主机的IP地址,在对方的MAC地址这一栏,填的是FF:FF:FF:FF:FF:FF,这表示这是一个“广播”地址。它所在子网络的每一台主机都会收到这个数据包,从中取出IP地址,与自身的IP地址进行比较。如果两者相同,都做出回复,向对方报告自己的MAC地址,否则就丢弃这个包。这样就可以把数据包发送到子网中任意一台主机上了。
4. 传输层
4.1 传输层的由来
有了MAC地址和IP地址,我们已经可以在互联网上任意两台主机上建立通信了。接下来的问题是,同一台主机上有许多程序都需要用到网络,比如,你一边浏览网页,一边和朋友聊天。当一个数据包从互联网上发来的时候,你怎么知道,它是表示网页的内容,还是聊天的内容?也就是说,我们还需要一个参数,表示这个数据包到底供哪个程序(进程)使用。这个参数就叫做“端口”(port),它其实是每一个使用网卡的程序编号。每个数据包都发送到主机的特定端口,所以统统的程序就能取到自己说需要的数据。
“端口”是0~65535之间的一个证书,正好是16个二进制位。0~1023的端口被系统占用,用户只能选用大于1023的端口。不管是浏览网页还是聊天,应用程序都会确定一个端口然后与服务器的相应端口联系。
“传输层”的功能,就是建立“端口到端口”的通信。相比之下,“网络层”的功能是建立“主机到主机”的通信。只要确定主机和端口,我们就能实现程序之间的交流。因此,Unix系统就把主机+端口,叫做“套接字”(socket)。
4.2 UDP协议
我们要在数据包中加入端口信息,这就需要新的协议。最简单的实现叫做UDP协议。
UDP数据包,也是由“标头”和“数据”两部分组成。
“标头”部分主要定义发出端口和接受端口,“数据”部分就是具体的内容。同样,UDP数据包是放入IP数据包的“数据”里的,前面说过,IP数据包又是放在以太网数据包的“数据”里的,所以最后整个以太网数据包变成下面的样子:
UDP数据包,“标头”部分一共有8个字节,总长度不超过65,535字节,因此正好可以放进一个IP数据包。
4.3 TCP协议
UDP协议的特点是比较简单,容易实现,但是缺点是可靠性较差,一旦数据包发出,就无法知道对方是否收到。
为了解决这个问题,提高网络的可靠性,TCP协议就诞生了。可以认为它是有确认机制的UDP协议,每发出一个数据包都要确认。如果有一个数据包遗失,就收不到确认,发出方就知道有必要重发这个数据包了。TCP协议的优点是确保数据不会一时。它的缺点是过程复杂、实现困难、消耗较多的资源。
TCP数据包和UDP数据包一样,都是内嵌在IP数据包的“数据”部分内。TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的长度,以确保单个TCP数据包不必再分割。
5. 应用层
应用程序收到“传输层”的数据,接下来就要就行解读。由于数据来源五花八门,必须事先规定好格式,否则根本无法解读。而“应用层”的作用,就是规定应用程序的数据格式。
比如,TCP协议可以为各种各样的程序传递数据,比如Email、WWW、FTP等等。那么必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了“应用层”。
这是最高的一层,直接面向用户。它的数据就放在TCP数据包的“数据”部分。因此,现在的以太网数据包就变成了这样。
至此,我们从系统的角度了解了TCP/IP原理了,全文结束。
参考资料:
http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html