网络通信协议(TCP/IP)

网络通信模式

大部分的网络应用系统可以分为连个部分:客户和服务器,而网络服务程序架构有两种一种是CS模式,一种是BS模式。

CS即Client/Server(客户机/服务器)结构,它的主要特点是交互性强、具有安全的存取模式、网 络通信量低、响应速度快、利于处理大量数据。但是该结构的程序是针对性开发,变更不够灵活,维护和管理的难度较大。并 且,由于该结构的每台客户机都需要安装相应的客户端程序,分布功能弱且兼容性差,不能实现快速部署安装和配置,因此缺少 通用性,具有较大的局限性。
BS即Browser/Server(浏览器/服务器)结构,就是只安装维护一个服务器(Server),而客户端采用浏览器(Browse)运行软件。B/S结构应用相对于传统的C/S结构应用程序是一个非常大的进步。B/S结构的主要特点是分布性强,维护方便,开发简单且共享性强,总体拥有成本低。但数据安全性问题,对服务器要求过高,数据传输速度慢,软件的个性化特点明显降低。

OSI七层网络模型(open system interconnection,开放系统互联)

 
是一个把网络通信在逻辑上的定义,也可以理解成为定义了通用的网 络通信规范。而我们的数据在网络中传输的过程,实际上就是如下图的封装和解封装的过程,发送方通过各种封装处理,把数据 转换成比特流的形式,比特流在信号传输的硬件媒介中传输,接收方再把比特流进行解封装处理。

1.物理层

        规定了如何为网络通信实现最底层的物理连接,以及物理设备的机械、电气、功能和过程特性。如何使用电缆和接头的类型、用来传送信号的电压。需要注意的是,网络通信过程中所需的物理媒介(网线,线缆等),其实并不属于物理层,因为物理层实际上是一种规定,规定这些物理媒介设备在连接网络时的各种规格,参数以及工作方式。但是同时,双绞线,线缆等物理媒介又是物理层的实现。

2.数据链路层

        规定了如何进行物理地址寻址、如何在物理线路上进行数据(帧frame)的可靠传递以及流量控制。数据链路层协议有SLIP协议、CSLIP协议、PPP协议等。交换机,对帧解码并根据帧中包含的信息把数据发送到正确的接收方,所以 交换机是工作在数据链路层的
链路层的。

3.网络层

  规定了通过哪些网络节点、什么样的网络路径来将数据(数据包)从发送方发送到接收方。在网络层中,确定了从节点A发数据到节点B的网络路径,经过哪些节点。网络层既可以建立LAN通信系统,更主要的是可以在WAN网络系统中建立通信,这是因为它有自己的路由地址结构,通过路由协议(又称可路由协议)进行网络通信的路由工作。

4.传输层

  负责总体的数据传输和数据控制,提供端到端的交换数据的机制。传输层对数据(段)进行分割和重组,并且进行流量控制和根据接收方的接收数据能力确定适当的传输速率。例如以太网无法处理大于1500字节的数据包,传输层将数据分割成数据片段,并对小数据片段进行序列编号。接收方的传输层将根据序列编号对数据进行重组。传输层协议有TCP协议、UDP协议等。

5.会话层

  在网络中的两个节点之间建立、维持和终止通信。

6.表示层

  在应用程序和网络之间对数据进行格式化,使之能够被另一方理解。即发送方的表示层将应用程序数据的抽象语法转换成网 络适用于OSI网络传输的传送语法,接收方则相反。除此之外,表示层还可对数据进行加密与解密。

7.应用层

  最顶层的OSI层,为应用程序提供网络服务。如为电子邮件、文件传输功能提供协议支持。应用层协议有HTTP协议、FTP协议,SMTP协议。
议、SMTP协议等。

TCP/IP协议

从“TCP/IP”名字上来看,貌似这只是tcp协议和ip协议,但是实际上,这是很多协议很多协议组成的一个协议集合,我们 把这集合统称为 TCP/IP协议族,简称为TCP/IP协议。对于TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。通过下图我们可以了解TCP/IP协议结构并对比了解学习TCP/IP 四层参考模型和 OSI 七层参考模型,因为TCP/IP太
过简单,我们也会使用模型化的TCP/IP五层模型来描述计算机网络。

TCP/IP——网络接口层

主要作用一: 数据封装/解封装成帧(frame)  为了保证可靠的传输,网络层传过来的数据在这里被加工成了可被物理层传输的结构包---帧。帧中除了包括需要传输的数据外,还包括发送方和接收方的物理地址以及检错和控制信息。其中的物理地址确定了帧将发送到何处,检错和控制信息则是用来保证数据的无差错到达。数据帧结构如下(Address均为mac地址):

主要作用二:控制帧传输。控制帧的传输的主要体现在反馈重发,计时器。帧序号方面。接收方通过对帧的差错编码(奇偶检验码或CRC)的检查,来判断帧在传输过程中是否出错,并向发送方进行反馈,如果传输方发送差错,则需要重发纠正。作为发送方,如果在发送帧后,会同时启动定时器,如果帧发送后在一段时间内没有收到反馈,为了避免传输停滞不前,则在定时器Timeout后认为帧传输出错,自动重发,为了避免多次收到同一帧并将其递交给网络层的情况发生,则需要对每个帧进行编号,接收从此以来判断该帧是否重复接受了。 

主要作用三:流量控制  由于收发双方各自使用的设备工作速率和缓冲存储空间的差异,可能出现发送方的发送能力大于接收方接受能力的现象,此时若不对发送方的发送速率做适当的限制,前面来不及接收的帧将被后面不断发送来的淹没,从而造成帧的丢失而出错,由此可见,流量控制实际上是对发送数据流量的控制,使其发送速率不超过接收方的速率。所以需要这些规则是的发送知道在什么情况下可以接着发送下一帧。而在什么情况下必须暂停发送,以等待收到某种反馈信息后再继续发送。 

TCP/IP——网络层

IP协议是TCP/IP协议族中最为核心的协议。所有的TCP,UDP,ICMP,IGMP协议数据都以IP数据报格式传输。IP协议提供的是不可靠的,无连接的数据报传输服务,不可靠是指IP协议不会保证数据报能否到达目的地,仅提供传输服务,传输出错,则会丢弃出错的数据报。无连接是指IP协议对数据报的处理是独立的,这一意味着接收方不一定会按照发送顺序接收数据报。IP数据报格式如下

 IP地址分类:

 

 子网划分:

子网掩码中的 1 标识了 IP 地址中相应的网络号, 0 标识了主机号。将 IP 地址和子网掩码进行逻辑与运算 ,结果就能得到网络号和子网号。

TCP/IP——传输层

        无论参考OSI还是TCP/IP的网络模型,我们从传输层向更底层看,各层的协议都是在直接或间接的服务于主机与主机之间的通信,而传输层则是在进程与进程通信层面上的。传输层有两个重要的协议——TCP(Transmission ControlProtocol,传输控制协议)和UDP(User Data  Protocol,用户数据报协议)
UDP协议:
        UDP即用户数据报协议,其传输机制决定了它的最大优点——快!,同时也决定了它最大的缺点——不可靠、不稳定。
        UDP是无连接的,发送数据之前不需要建立连接(TCP需要)。减少了开销和延时。
        UDP是面向报文的,对IP数据报只做简单封装(8字节UDP报头)。减少报头开销。
        UDP没有阻塞机制,宁愿阻塞丢失数据不传,也不阻塞造成延时。
        UDP支持一对一,一对多,多对一,多对多通信。
UDP报文结构:
        

 TCP协议

        TCP(Transmission Control Protocol)传输控制协议,相对于UDP,TCP是面向连接的,提供可靠的数据传输服务。同时也是较UDP开销较大的,传输速度较慢的。

        TCP提供可靠的,面向连接的数据传输服务。使用TCP通信之前,需要进行“三次握手”建立连接,通信结束后还要使用“四次握手”断开连接。

        TCP是点对点的连接。一条TCP连接只能连接两个端点。                                                                  TCP提供可靠传输,无差错,不丢失,不重复,按顺序。                                                                  TCP提供全双工通信,允许通信双方任何时候都发送数据,发送方设有发送缓存,接收方设有接收缓存。                                                                                                                                              TCP面向字节流。TCP并不知道所传输的数据的含义,仅把数据看作一连串的字节序列,它也不保证接收方收到的数据块和发送方发出的数据块具有大小对应关系。

TCP报文结构

 TCP是面向字节流的,通过TCP传送的字节流中的每个字节都按顺序编号,而报头中的Sequence Number 字段则指的是本报文段数据的第一个字节的序号,Avknowledgment Number是期望收到对方下个报文段的第一个数据字节的序号。

Offset : 占4位,指TCP报文段的报头长度,包括固定的20字节和TCP Options字段。                    Reserved : 占6位,保留为今后使用,目前为0。                                                                            TCP flags的C、E、U、A、P、R、S、F字段用来说明改报文的性质。意义如下:

C(CWR)和E(ECE) 用来支持ECN(显示阻塞通告)                                                                    U(URGENT):当 URG=1时,它告诉系统此报文中有紧急数据,应优先传送(比如紧急关闭),这要与紧急指针字段配合使用。                                                                                                     A(ACK):仅当 ACK=1时确认号字段才有效。建立 TCP 连接后,所有报文段都必须把 ACK 字段置为 1。                                                                                                                                         P(PUSH):若TCP连接的一端希望另一端立即响应,PSH字段便可以“催促”对方,不再等到缓存区填满才发送。                                                                                                                        R(RESET):若 TCP 连接出现严重差错,RST 置为 1,断开 TCP 连接,再重新建立连接。 S(SYN):用于建立和释放连接,当SYN=1时,表示建立连接。                                                    F(FIN):用于释放连接,当 FIN=1,表明发送方已经发送完毕,要求释放TCP 连接。              Window:占2个字节。窗口值是指发送者自己的接收窗口大小,因为接收缓存的空间有限。 CheckSum:占2个字节。和UDP报文一样,有一个检验和,用于检查报文是否在传输过程中出差错。                                                                                                                                                    Urgent Pointer:占2字节。当URG=1时才有效,指出本报文段紧急数据的字节数。

TCP建立连接的三次握手

1.Client首先向Server发送连接请求报文段,同步自己的seq(x),Client进去SYN_SENT状态。2.Server收到Client的连接请求报文段,发回给Client自己的seq(y)以及ack(x+1),Server进去SYN_REVD状态。                                                                                                                    3.Client收到Server的返回确认,再次向服务器发送确认报文段ack(y+1),这个报文段已经可以携带数据了。Client进入ESTABLISH状态。                                                                                            4。Server再次收到Client的确认消息后,进去ESTABLISH状态。

TCP连接至此建立起来了。为什么要做三次握手呢?握手的过程实际上是在通知对方自己的初始化序号(Initila Sequence Number)简称ISN,也就是图上的x和y。x和y会被当做之后传输的一个依据,以保证TCP报文在传输过程中不会混乱。

对于TCP Header的结构来看,Sequence Number和Acknowledgment都是占32位,所以seq和ack的取值范围都是0~2^32-1。seq和ack每增加到2^32-1,都会置为0。值得一提的是,seq的初始值(ISN)并不是每次都从0开始的。我们设想一下,如果是0开始,那么当TCP三次握手建立连接完成后,Client发送了30个报文,然后Client断线了,于是Client重连,再次用0作为初始化的seq,这样就会出现两个报文具有相同的seq,就出现了混乱,事实上TCP的做法是每隔4微秒就对ISN做一次加1的操作,当ISN到达2^32-1后再次从0开始的时候,已经过去了几个小时,之前seq=0的报文已经不存在于这次的连接中了,这样就避免了上面的问题。

TCP断开连接的四次握手

1.Client向Server发送断开连接的请求报文段,seq=m(m为Client最后一次向Server发送报文段的最后一个字节序号加1),Client进入FIN-WAIT状态。                                                                              2.Server收到断开报文段后向Client发送确认报文段,seq=(n为Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入CLOSE-WAIT状态。此时这个TCP连接处于半开半闭状态,Server发送数据的话,Client仍然可以接收到。                                                                  3.Server向Client发送断开确认报文段,seq=u(u为半开半闭状态下Server最后一次向Client发送报文段的最后一个字节序号加1),ack=m+1,Server进入LAST-ACK状态。                                            4.Client收到Server的断开确认后报文段后,向Server发送确认断开报文seq=m+1,ack=u+1,Client进入TIME-WAIT状态。                                                                                                                     5.Server收到Client的确认断开报文,进入CLOSED状态,断开了TCP连接。                                  6.Client在TIME-WAIT状态等待一段时间(时间为2*MSL)(Maximum Segment Life),确认Client向Server发送的最后一次断开确认到达(如果没有到达,Server会重发步骤(3)中的断开确认报文段给Client,告诉Client你的最后一次确认断开没有收到)。如果Client在TIME-WAIT过程中没有再次收到Server的报文段,就进入CLOSED状态。TCP连接至此断开。                                                      

TCP可靠连接的体现:

1.TCP报文段的长度可变,根据收发双方的缓存状态,网络状态而调整。                                         2.当TCP收到发自TCP连接另一端的数据,他将发送一个确认。                                                      3.当TCP发出一个段后,他启动一个定时器,等待目的端确认收到这个报文段,如果不嗯呢该几首收到一个确认,将重发这个报文段。                                                                                                4.TCP将保持这它首部和数据的校验和,如果通过校验和发现报文段有错,这个报文段将被丢失,等待超时重传。                                                                                                                               需要注意的是,TCP报文传输采用接收后返回确认的方式来保证报文传输的可靠性,并不是意味着发送方在发送一个报文段后就进入等待确认状态,让后面的报文段等着。也不是接收方在接收到一个报文后,对每一个报文都进行回复确认。                                                                                    真实的情况是,对于发送方,在发送一个报文段后,复制一份该报文段的副本,然后继续进行下一个报文段的发送,如果没 有得到发送方的回复确认,就对该报文段进行超时重发。对于接收方来说,则采用“积累确认”的方式进行回复。接收者收到多个连续的报文段后,只回复确认最后一个报文段,表示在这之前的数据都已收到。以此达到提升传输效率的目的。

 TCP流量控制:

由于收发双方缓存的限制,发送窗口不能大于接收方接收窗口。在报文段首部有一个字段就叫做窗口(rwnd),这便是用于告诉对方自己的接收窗口,可见窗口的大小是可以变化的,这个叫做滑动窗口协议。

 

    总结起来如上图,TCP的流量和阻塞控制采用“慢启动”、“加性增”、“乘性减”的策略。
  慢启动:初始的窗口值很小,但是按指数规律渐渐增长,直到达到慢开始门限(ssthresh)。
  加性增:窗口值达到慢开始门限后,每发送一个报文段,窗口值增加一个单位量。
  乘性减:无论什么阶段,只要出现超时,则把窗口值减小一半。

TCP/IP——应用层

关于应用层协议,不同的应用或者具体来说同一种应用不同的需求,都会使用不同的应用层协议。下面是常见的应用协议使用的端口:

端口号名称说明
20ftp-dataFTP(数据端口)
21ftp文件传输协议(FTP)控制端口
22ssh安全Shell(SSH)远程登录服务
23telentTelnet远程登录服务
25smtp简单邮件传输协议(SMTP)
53dns域名服务(Domain Name Server)
69tftp简单文件传输协议
80http用于万维网(WWW)服务的超文本传输协议
123ntp网络时间协议(NTP)
161/162snmp简单网络管理协议(SNMP)
443https

安全超文本传输协议(HTTPS)

1433mysqlmysql数据库服务程序默认端口
8080tomcatjava服务器程序默认端口

因为端口号是16位的。这也意味着端口号的范围是0~65536。其中1~1024是被RFC3232规定好了的,被称作"众所周知的端口",监听该范围内的端口程序必须以ROOT权限运行;从1025~65535端口被称为动态端口(Dynamic Ports),可以来建立与其它主机的会话,也可由用户自定义用途。所以我们在写服务器程序时,一般使用该范围内的端口,当然应该避免一些知名的端口或当前正在使用的端口。我们可以通过sudo  netstat  -tlnp查看被监听的端口。

一台服务器主机可以提供多种服务,譬如一台Linux主机可以提供SSH服务,这样我们就可以使用SSH西医的客户端软件(如SecureCRT,Putty)来远程登录控制;当然也可以在Linux主机上同时提供web服务,这样我们就可以通过浏览器访问架设在主机上的网站。 对每一个服务,都会有一个相应的程序在后台默默地运行着提供相应的服务,其中openssh或dropbear就是实现ssh协议额的服务程序,apache,nginx,httpd,boa等是提供web访问的web服务器。既然同一台服务器可以提供这么多服务,那么当某个客户端程序访问服务器的时候,系统 怎么知道该客户端是访问哪个服务器程序,这也决定了从网卡上收到的数据包究竟该给哪个服务器程序。其实,每一个服务器程 序都会监听一个特定的端口,并且这个端口不可被其他程序重用,同时每一个客户端在访问某个服务器时,除了指定服务器的地 址(包括域名和IP地址)还需要说明要访问哪个端口,那么从该客户端过来的数据系统会给监听相应端口的服务器程序。

在很多客户端软件上,如果没有指端口的话譬如我们使用浏览器上网,通常只是输入域名(如www.baidu.com),而并没有端口,事实上这是因为浏览器会默认访问80端口。而如果想访问某个特定的端口,我们可以在域名后添加相应的端口来访问,如:https://baidu.com:443,用该地址可以访问百度服务器的443端口。在这里得实例中,www指定是http协议,https指定的是https协议,baidu.com指定的是百度的域名,系统会查询DNS将该域名转换成IP地址,而:443则指定访问的端口,SSL默认使443端口。

举例子:

接下来,我们以下图为例,讲解客户端(192.168.0.3) 通过浏览器访问百度服务器( baidu.com )的过程,在这里我们不讨论HTTP协议,而只是以“你好,百度!”代表相应的应用层数据

 

 

客户端发送数据给服务器的流程:
1, PC上浏览器希望发送“百度,你好!”这个数据给百度服务器,因为百度服务器的IP地址(220.181.57.216)不好记,所以我们访问某个服务器时通常都不是使用IP地址,而是域名(baidu.com)。但在计算机网络TCP/IP协议栈中是通过IP地址来标识每一
个结点的(包括主机、无线路由器等),这时我们需要一种机制将域名翻译成相应的IP地址,这个工作就是DNS。所以 PC(192.168.0.13)首先要给域名服务器(如114.114.114.114)发送一个域名解析请求,将百度的域名baidu.com 转换成相应的IP 地址220.181.57.216。所有的Linux系统,域名服务器都在 /etc/resolv.conf 配置文件中指定。如果系统能聊QQ但不能通过域 名访问网页,就要检查DNS的设置是否正确;
2, 浏览器发出“百度,你好!”的数据报文,该数据报文通过系统调用进入到操作系统内核里的TCP/IP协议栈,首先进入到 TCP层会在应用层发过来的数据上加入20字节的TCP头,在TCP头部包含两个重要的信息,即源端口和目的端口。其中目的端口
是百度的web服务器监听的80端口,而源端口如果没设定的话就由操作系统内核动态分配一个未使用的端口,如上图中的 8888;
3, 紧接着数据报文走到下层IP层,该层会在TCP数据包的基础上再加一个20字节的IP头,在IP头里有两个非常重要的信息,即 源IP和目的IP,这里的源IP就是客户端PC的IP 192.168.0.13,而目的IP就是百度服务器的IP地址 220.181.57.216;
4, 数据包到达物理层以二进制形式通过电磁信号发送出去,因为在该报文中出现的目的IP地址(220.181.57.216)和源IP地址 (192.168.0.13)不在一个网段内,则计算机会将该数据包发送给默认网关,也就是PC所连的路由器;
5, 无线路由器收到来自PC的数据包,因为源IP 192.168.0.13是个私有IP,不能出现在Internet公网上,所以他会把数据包中的 私有IP(192.168.0.13)替换成自己的公网IP(110.110.110.110),同时将源端口(8888)也转换成自己的临时端口 9999,
并记录这条转换记录到NAT表中去 6, 经过局域网上的路由器做了NAT转换之后的源IP和目的IP都是公网IP了,这时候就通过Internet上的节点转发到百度的服务
器上;
7, 百度的服务器在网卡上接收到数据包后,操作系统内核的IP层首先检查数据包里的目的IP是不是本机IP,如果不是就将数据 包直接丢掉;否则就会去掉20字节的IP头后扔给上层的TCP层继续处理;
8, 在TCP层会查看该数据包里的端口号是多少,经查询目的端口号是80,而刚好百度服务器上的web服务器程序nginx监听着 该端口。这时他首先将20字节的TCP头去掉,获取应用层数据“你好,百度!”,然后将该数据传给nginx服务程序而不是其他 程序处理;
服务器回复数据给客户端的流程
9, 百度服务器在收到客户端的数据之后,假设需要给客户端回复数据“你好,客户端!”,该数据将会进入到操作系统内核的 TCP/IP协议栈,在TCP层将之前的源端口(9999)设置成目的端口,并将目的端口(80)设置成源端口;
10,紧接着数据报文走到下层IP层,该层也将之前的源IP(110.110.110.110)改成目的IP,并将目的IP(220.181.57.216)改
成源IP;
11,数据报文到达物理层通过无线电发送给相应的无线路由器,并经过Internet到达对端的无线路由器;
12, 无线路由器就相当于一个快递员,他只是负责转发这些数据并不接收并处理数据,在同一局域网下有很多电脑,这时他该 把数据发给谁呢?这时会查询之前数据发送出去记录的NAT表,这时候会发现之前的源IP和源端口 192.168.0.13:8888被替换成
了110.110.110.110:9999,那么现在到110.110.110.110:9999的数据报文就该给主机 192.168.0.13 的8888端口。路由器会 将该数据包中的目的IP和目的端口换掉,然后发送给相应的主机;
13, 主机192.168.0.13接收到路由器发送过来的数据后,在IP层验证IP地址是否是本机IP,如果是本机IP则去掉20字节的IP头并 给TCP层继续处理,TCP层确认目的端口号(8888)后去掉20字节的TCP头,并将服务器的数据“你好,客户端!”发给使用该
端口的浏览器。
14, 浏览器收到服务器端的数据后就解析HTTP数据并显示出来,完成整个服务器访问的流程。
从上面的整个流程中,我们会发现 一个TCP的网络链接中求包含一个四元组,即: 源IP、目的IP 和 源端口、目的端口。这就 像我们收发快递一样要有发件人和发件人地址、收件人和收件人地址一样。 在理解上面的计算机网络通信的工作原理之后,接下 来我们就可以更好的理解Linux下的网络socket程序开发了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值