OSI七层网络模型
百度百科
- 开放式系统互联通信参考模型(英语:Open System Interconnection Reference Model,缩写为 OSI),简称为OSI模型(OSI model),一种概念模型,由国际标准化组织提出,一个试图使各种计算机在世界范围内互连为网络的标准框架。定义于ISO/IEC 7498-1。
层次划分
-
物理层(Physical Layer) 在局部局域网上传送数据帧(data frame),它负责管理计算机通信设备和网络媒体之间的互通。包括了针脚、电压、线缆规范、集线器、中继器、网卡、主机适配器等。
-
数据链路层(Data Link Layer) 负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成帧。数据链表头(DLH)是包含了物理地址和错误侦测及改错的方法。数据链表尾(DLT)是一串指示数据包末端的字符串。例如以太网、无线局域网(Wi-Fi)和通用分组无线服务(GPRS)等。
-
网络层(Network Layer) 决定数据的路径选择和转寄,将网络表头(NH)加至数据包,以形成分组。网络表头包含了网络数据。例如:互联网协议(IP)等。
-
传输层(Transport Layer) 把传输表头(TH)加至数据以形成数据包。传输表头包含了所使用的协议等发送信息。例如:传输控制协议(TCP)等。
-
会话层(Session Layer) 负责在数据传输中设置和维护计算机网络中两台计算机之间的通信连接。
-
表示层(Presentation Layer) 把数据转换为能与接收者的系统格式兼容并适合传输的格式。
-
应用层(Application Layer) 提供为应用软件而设的接口,以设置与另一应用软件之间的通信。例如: HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。
TCP/IP五层/四层模型
实际我们运用中,主要用到的是五层或四层模型,真正实现七层协议的不多。
五层网络模型
将应用层、表示层、会话层合起来统一叫做应用层
四层网络模型
四层是在五层的基础上,将数据链路层与物理层合并为“网络接口层”
对于我们程序员
TCP/IP五层或者四层是最常用的。我们发布的程序代码,如Java程序,正是位于应用层,我们自己去处理会话、表示等工作。传输控制层由OS操作系统控制网卡去处理,网络层、数据链路层、物理层由路由器、交换机、集线器等等网络设备处理
物理层
我们用一根网线将两台电脑连接起来,就构成一个最小型的局域网(以太网),就可以开始愉快的打开红色警戒之共和国之辉进行联机PK了。
此时又有一个小伙伴想加入,那我们买一个集线器,将电脑都连接到集线器上
但是集线器这个东西,智商很低,通讯就是靠吼,电脑1发给电脑2 的消息,同样也会发给电脑3,电脑4。广播的形式
数据链路层
于是我们买了交换机,往高层走走,那么交换机是怎么知道每个电脑的位置的呢,电脑1发给电脑2的消息,怎么找到电脑2的呢。于是就用到了Mac地址,每台设备出厂时在网卡上的全世界唯一标识。交换机比如有5个插口,在内部只需要维护一张映射表,插口1对应电脑1的mac地址,2对应2 。。。依次类推,这样当电脑1发送一条消息给电脑2,通过交换机,一看映射表,就知道这个消息应该从插口2传出去,那就准确的发给了电脑2,而不是像集线器一样傻。
-
那这个映射表是哪来的?
我们刚买的交换机里面映射表是空的,当电脑1发送消息给电脑2的时候,一开始它并不知道电脑2的mac地址,那么先来一次广播,发给所有电脑,其他电脑拒绝接受,只有电脑2接受了,也就是只有插口2返回了true,并且给了自己mac地址,那么映射表了就有了插口2对应电脑2的mac,随着机器之前不断通讯,这样一步步完善映射表。
-
发送的数据包是什么样的
基于以太网协议,数据链路层的报,由一组电平信号构成,叫做“帧”,每一数据帧由报头Head和数据Data组成
数据包的具体格式:Head + Data = 最短64字节,最长1518字节(超出限制则分片发送) -
Mac地址
Head中包含源Mac与目标Mac
Mac地址是一个长度为48位的二进制数,通常用12位的16进制数表示,前6位厂商编号,后6位流水线号
网络层
有一天,我家终于办网了,买了一个路由器,再也不用插线到交换机上了,虽然说无线AP也能解决插线的问题,但是我们也想跟网上的人碰一碰,毕竟红警练了这么久,家里没对手,该去外面的世界看看了
-
先看下网络层涉及的知识点:
-
IP(Internet Protocol)
IPv4规定网络地址由32位的二进制表示,00000000111111111111000011110000,类似这样的,但是人看起来不太爽,于是转换为10进制来显示和设置,当然底层还会转会2进制,如19216811,由增加了“.”的分隔符,看起来更舒服些,192.168.1.1。IPv4的取值范围是0.0.0.0~255.255.255.255,为什么是255因为每个三位十进制表示的8位二进制,2的8次方是256,从0开始算就是0~255
-
子网掩码:
表示子网络特征的一个参数,由32位的二进制表示,形式上类似IP地址,如 11111111.11111111.1111111.0000000,为1的部分是表示网络的部分,为0 的部分表示主机,转成十进制就是255.255.255.0,有多少个1就表示掩码位是多少。因为子网掩码这个东西被设计出来就是表示子网特征的,他的作用就是这个,那么1就是他的特征,比如现在是24个1,所以结合IP表示为192.168.1.1/24,这才是一个完整的IP地址。
什么是主机部分?如上图,第一可用、最后可用。
刚刚的掩码,后面是8个0,那么就能给256个网卡分配地址,当然,一般会给保留0和255这两个头和尾,所以可用的IP就是254个。8个0的IP作为网络号,代表这个局域网,8个1的IP作为广播地址,用于给同一链路中的所有主机发送数据。-
IP数据包
也分为Head(20~60字节)与Data(max65515字节)两部分,IP数据包直接放入以太包的data里
由于以太包Data最长1500字节,超出的话,进行分片发送,比如发4000字节的IP包,那么得分为四个包发送,1500 + 1500 + 1500 = 3500字节,还剩500没发完,前面每个包都得单独加一个IP头,所以最后一个包是 500 + 20 + 20 + 20 = 560字节,全部发完。 -
ARP
用于实现从IP地址到Mac地址的映射,即询问目标IP主机的Mac地址,以广播的形式发送数据包,获取主机的Mac地址,然后在本地缓存ARP映射表。
-
-
IP包发出去是怎么到达目标主机的?
首先IP数据包头里有源IP与目标IP,通过两个IP分别与当前子网掩码进行二进制位运算,得到结果如果一致,说明两个IP是在一个子网下,如果不一致就不在。这也是子网掩码的主要作用。
-
在一个子网下:
192.168.0.2 发送消息给 192.168.0.100,先在自己的ARP缓存里找下,如果找到,将IP数据包发给二层网络设备接收,拆第一层的以太包的Head,得到目标Mac地址,从对应的端口将数据包发出去。
-
不在一个子网下:
192.168.0.2 发送消息给 192.168.0.100,将数据包发给网关(其实还是在本地ARP映射表里一条一条匹配,只不过没匹配上,最后有一条是网关的,匹配任何项),网关就是路由器,路由器拿到后在跟自己本地ARP进行匹配,因为他可能连这多个交换机,如果能匹配上,就发给那个交换机,如果匹配不上,走下一跳。到另一个局域网。知道最后跳到能匹配上的路由器。所谓吓一跳,就是下一个路由器的IP,比如你家是移动网,那你家路由器下一跳就去了移动的路由器了。
-
今天买了一个高仿苹果手机,收件人是我,在北京大兴区西红门宏福路8号柴子,卖家是广东华强北张三。从广东往北京发走了三天,在南京、上海、哈尔滨中转了好几次,不知道为什么去哈尔滨。。。。收件人和发件人从始至终没有变,中转站一直变。在数据包中,IP包里的源IP与目标IP一直不会变。以太包里的源Mac与目标Mac经历一次中转变一次。
IP既然能唯一确定一个主机,为什么还要Mac地址?
IP确实能唯一表示一个主机,但是在网络里传输的过程,需要Mac地址,好比你从广东某个地方到北京某个地方,除非你有私家车,就像拉网络专线。要不然你就得坐公交,坐火车,打车,一步步的过来。当你出发的时候,你的源Mac地址是你出发的地方,目标Mac就是公交站,然后到了公交站,你的源Mac就变成公交站,目标Mac就变成了火车站。。。。。。你毕竟没专线,只能通过运营商搭建的各种中转站下一跳,下一跳,直到跳到地方。最终找到主机也是在最后一个网络设备,将目标Mac改成目标主机的Mac地址。
传输控制层
现在我们已经知道,网络层IP地址帮我们区分子网,跳到目标的第三层网络设备上,以太网层的Mac地址帮我们找到目标主机。
-
这时候问题又来了,我们主机上启动了很多程序,微信、QQ、数据库,他怎么发到对应的程序上的呢?
这就是传输控制层的事了,利用端口到端口的通信机制
-
TCP(Transmission Control Protocol)
定义:面向连接的可靠的传输控制协议。
理论上TCP的数据包没有长度限制,但是为了保证网络的效率,通常不会超过IP数据包的长度(65515字节),确保TCP包不必再分割
-
Head主要包含源端口,目标端口,序号与确认号,数据偏移、标志位等等
-
端口:由源IP、源port、目标IP、目标port的四元组确定唯一一条TCP连接,端口就好比交换机或者路由器的那个插口,只不过那是物理的,这是逻辑上的,由OS操作系统管理。端口号底层是16位无符号的2进制表示,所有一共65535个,
-
序号:用来确保TCP数据传输的有序性,接收方可根据需要来组装数据,有可能因为网络原因,后发的数据先到,由序号来保障数据的准确组装
-
确认号:即ACK,指明下一个期待收到的字节序号,1 为有效
-
数据偏移:或者叫头部长度更好理解,由于TCP头部长度不固定,指示数据区在报文的起始偏移值
-
标志位
字段 名称 含义 URG 紧急指针标志 1表示紧急指针有效,0则忽略 ACK 确认序号标志 1表示确认号有效,0表示报文中不含有确认信息,忽略确认号属性 PSH 接收信号标志 1表示带有PUSH标志的数据,指示接收方在接收到该段报文后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队 RST 重置连接标志 用于重置由于主机崩溃或其他原因而出现的错误的连接,或者用于非法的报文段和拒绝连接请求 SYN 同步序号标志 用于建立连接的过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1 FIN 完成标志 用于释放连接,1表示发送方已经没有数据发送了,即关闭本地数据流
-
好了,有了这些个前置知识,我们终于可以进入正题了。网络编程,到了我们开发的活了。
TCP连接
建立连接
-
是个开发都知道,三次握手,我们用抓包工具看下
-
前置命令
-
nc命令,与服务端建立一个tcp连接
-
tcpdump抓包命令 -nn 数值显示方式,-i 抓的接口, 端口号
- tcpdump -nn -i eth0 port 80
-
ifconfig 查看当前IP和网卡号
-
-
执行
tcpdump -nn -i eth0 port 80
我的macbook电脑网卡号是en1-
新开一个终端,执行nc 命令访问百度
nc www.baidu.com 80
与百度建立TCP连接
-
抓包结果
17:05:40.503857 IP 10.1.237.75.56805 > 110.242.68.3.80: Flags [S], seq 904701215, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3234389048 ecr 0,sackOK,eol], length 0 17:05:40.525968 IP 110.242.68.3.80 > 10.1.237.75.56805: Flags [S.], seq 1703058665, ack 904701216, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0 17:05:40.526153 IP 10.1.237.75.56805 > 110.242.68.3.80: Flags [.], ack 1, win 4096, length 0
-
客户端给服务端发送syn请求连接,第一次握手
-
服务端给客户端回syn+ack确认,第二次握手
-
客户端给服务端发送ack确认,第三次握手
连接建立完成
为什么是三次握手?
-
老师给学生上网课,老师讲完说,听懂的扣1 !! 第一次握手。
-
学生开始发送1给老师,第二次握手。好像就可以完事了。但是如果老师现在在哪不说话,那学生肯定一直不停的发1,因为他们不知道老师到底看到1没,老师也不说话,也不说停。
-
老师现在说好了,都听懂了咱们继续。第三次握手。
为什么说TCP是可靠的,为了保证可靠性,三次是必须的。
-
-
断开连接
-
是个开发都知道,四次挥手/分手,同样用抓包工具看下
-
执行
tcpdump -nn -i eth0 port 80
-
另一个窗口执行
curl www.baidu.com
-
抓包结果
17:26:33.531849 IP 10.1.237.75.49169 > 110.242.68.3.80: Flags [F.], seq 78, ack 2782, win 4096, options [nop,nop,sack 1 {1441:2782}], length 0 17:26:33.540606 IP 110.242.68.3.80 > 10.1.237.75.49169: Flags [.], ack 79, win 908, length 0 17:26:33.540612 IP 110.242.68.3.80 > 10.1.237.75.49169: Flags [F.], seq 2782, ack 79, win 908, length 0 17:26:33.540741 IP 10.1.237.75.49169 > 110.242.68.3.80: Flags [.], ack 2783, win 4096, length 0
连接断开完成为什么是四次挥手?
-
你媳妇找你,这是离婚协议书,你签字吧,第一次挥手。
-
你说行。第二次挥手。
-
然后你签字了,跟他说签完了。第三次挥手,
-
她说行。第四次挥手
你和她都如释重负,各自跑路了。其实服务器和客户端也是一样的,他们连在一起的时候,是需要消耗资源的,是有负担的。所以两边都得互相同意,互相询问,才能放心的把这个重担释放。
-
Socket
-
建立在TCP/UDP之上的、传输控制层与应用层之间的一个抽象层。
-
什么是套接字?
所谓套接字,实际上是一个通信端点,每个套接字都有一个套接字序号,包括主机的IP地址与一个16位的主机端口号,即形如(主机IP地址:端口号)。例如,如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)。
总之,套接字Socket=(IP地址:端口号),套接字的表示方法是点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。每一个传输层连接唯一地被通信两端的两个端点(即两个套接字)所确定。
-
我们的代码是属于应用层的,而下层都是由操作系统去管理和操作的,比如我们的Java程序想跟百度建立连接,那我们需要使用io包里的Socket是建立,而实际底层是走的系统调用,因为建立连接这个事是由网卡发出去的,网卡只有操作系统可以控制。建立TCP连接的传输控制层是跟我们的应用没什么关系的。当通过Socket创建好TCP连接后,会返回给我们程序一个文件描述符,并且系统会开辟文件描述符指向的内存空间共我们进行读写,对我们的程序而言,建立的Socket连接,我们只是得到这样一个文件描述符。其他什么都不知道。当对方发送过来数据时,我们可以用这个文件描述符去读取数据,当我们想发送数据的时候,我们通过文件描述符往内存里写数据,系统会帮我们从网卡发出去。
所以对我们程序而言,连接就是一个文件。或者说,对操作系统而言,一切皆文件。
Http
当了解了这些,我们再来聊HTTP,它属于应用层的内容,我们的程序也是这一层,那么它就是完全在我们程序的控制范围内,由我们程序与处理,比如Nginx,Tomcat,LVS等等,或者我们自己写一个处理器处理Http,解析它的报文,处理响应它的报文。
Http协议,什么是协议,就是一种约定,一种规范。你建立好连接后,按照Http协议的格式发送数据,解析数据,就可以进行Http通讯。那既然这样,我们自己定义一套规范如何啊。所以出现了RPC远程过程调用(Remote Procedure Call)