2.TCP协议
2.1概念:
- TCP是传输控制协议,是面向连接的、可靠的、基于IP协议的传输层协议。
2.2报文结构
-
报文每一行长度是32bit,4个字节。
-
第一行,是端口号,包括两部分,两个端口,分别是源端口和目的端口
-
第二行,是32位的一个序号
- 序号负责对传输的数据字节进行顺序的编号,以保证传输的数据顺序一致(因为网络传输的过程中,数据的顺序可能错乱)
-
第三行,是确认号
- 确认号用来标识接收端确认收到的数据段。确认号是收到的数据序号+1,然后发给对方,代表我要接着收你的下一个数据序号开始的数据段。
-
第四行,数据偏移以及一些用于通信的标志位字段,数据偏移这个数字就是告诉我们这个数据报文的首部到底有多长。因为首部的长度是不固定的,首部长度至少20字节,最多60字节。但长度一定是4字节的整数倍。(最后有个填充部分就是保证整数倍)
-
标志字段:
-
URG:urgent代表紧急,当它为1时生效,代表报文中有紧急数据需要处理,尽快交给应用程序处理,而不是按顺序从接收缓存中读取。
-
ACK:Acknowledgment代表确认,为1时生效,此时确认序号才有效,为0时无效。
-
PSH:push代表推送,为1时生效,希望对方马上给我响应,当收到PSH为1的报文后,就马上给对方响应,而不需要等到缓存队列满了之后再响应。
-
RST:reset代表复位,为1时生效,当遇到严重错误的时候,就需要复位,释放连接。
-
SYN:synchronous代表同步代表请求连接,为1时生效。配合ACK来使用
-
SYN=1,ACK=0,表示这是一个建立连接请求的报文。客户端发出。
-
SYN=1,ACK=1,表示确认收到并同意建立连接的响应报文。服务端发出。
-
-
FIN:finish代表终止,为1时生效,用来释放一个连接,表明数据已经传输完毕,可以断开连接了。
-
-
-
第五行,校验和、紧急指针。校验和是一个端到端的校验,由发送端来计算,由接收端来验证。目的就是校验数据在传输过程中有没有被修改或丢失等异常情况。如果接收端检测到校验和不对,那就会丢弃报文。TCP协议的校验和针对报文的首部和数据部分都会做校验。IP协议只会对首部做校验。
-
2.3三次握手建立连接
-
为什么需要三次握手,只有这样才能建立可靠连接。
-
第一次握手,发送端向接收端发出连接请求,等待响应
-
第二次握手,接收端响应,通知发送端收到了连接请求。
-
第三次握手,发送端再次发送确认信息,告诉接收端我收到了你的信息。
-
两次握手不行,比如:B不知道A有没有收到B的回复报文。又比如:A由于网络原因,给B发了两次建立连接的请求,这时候B无法判断第二次的请求是重复的,B只能选择接受或放弃,但A可以通过第三次握手判断,因为确认号一样就证明重复了,那就放弃。所以,两次握手会导致重复连接,三次则不会,四次握手没必要。
-
重复连接的情况:
-
2.4四次挥手断开连接
-
建立连接我们都知道需要三次握手,但是断开连接却需要四次挥手才可以,这多出来的一次是用来断开数据的。客户端可以主动发送FIN信号告诉服务端我要跟你断开了,此时服务端收到断开信号后可以马上回消息ACK确认,告诉客户端我收到你的断开请求了,但此时服务端的数据可能还没发完,所以服务端需要等待一段时间,确认数据发完了才能发送FIN信号给客户端,客户端收到服务端的断开信号后,确认服务端的数据也发完了,再发一个确认信号ACK,这样才正式断开连接。然后客户端还需要等待两个报文周期,因为它不确定最后回的确认消息,服务端收到没。如果服务端没有收到这个确认报文,服务端会重新发送FIN报文。只有客户端等了两个报文周期都没有收到重新发来的FIN报文,才表示服务器确定收到了ACK报文,就可以断开了。
3.UDP协议
-
用户数据报协议,它是面向无连接的,不可靠的传输层协议。
-
数据传输时,发送端和接收端不建立逻辑连接。不需要知道对方在不在,直接发数据,接收方只管接数据,也不需要告诉发送端是否收到数据。
4.IP协议
- 网络层协议,负责网络的寻址。
4.1 报文格式
-
4位版本号:(IPV4, ipv6)
-
4位首部长度:IP协议报头的长度。
-
8位服务类型:最小延时,最大吞吐量,最高可靠性,最小成本。
-
16位总长度:IP协议的长度。(0-64k)
-
分包组包:如果一个协议太长了,我们需要分成多份,为了弄清楚描述这些小包是哪个打包,需要用下面的字段。
-
标识:同一个IP包使用同一个标识,表明原来都是同一条协议的。
-
标志:是否是最后一个包。(0不是最后一个包,1是最后一个包)
-
偏移量:标识包的前后顺序,也就是原来的IP协议的位置。
-
8位生存时间:IP协议可以被路由器或者交换机转发的次数。(有的IP地址是不存在的,是永远找不到的,所以这个包一直转发就没有任何意义了,就需要把他抹杀掉)
-
8位协议:指传输层的协议(TCP, UDP)
-
16位首部校验和:校验是否在传输过程中发生什么错误。
-
源IP地址,目的IP地址:IP地址是32位,我们一般使用点分十进制,将32位点分4份,每份8位,然后用10进制表示。
4.2 IP地址和网段划分
-
IPV4地址共32位,由两部分构成:网络号+主机号
-
同一局域网下的设备网络号都是一样的
-
主机号就是设备的号码,各不相同
-
-
子网掩码
-
用来确定网络号占多少位。
-
子网掩码的表示方式:
-
192.168.1.1/24 表示前24位是网络号
-
也可以表示成:255.255.255.0
-
-
网络号=子网掩码与IP地址进行与运算,也就是把IP地址的主机号都设为0
-
-
子网划分
-
为了提高网络查找效率,确定标准,在世界范围内指定了不同的网段,也就是不同的子网。当然,在此基础上,我们还可以通过子网掩码,指定自己的网络号,继续划分更小的子网。
-
举例1:
-
IP地址:140.252.20.68
-
子网掩码:255.255.255.0
-
网络号:140.252.20.0
-
这个子网的IP地址范围:140.252.20.0-140.252.20.255(实际能使用的IP地址还要减2,因为主机号部分全零是网络号,全1是广播地址)
-
-
举例2:
-
IP地址:140.252.20.68
-
子网掩码:255.255.240.0 前20位是网络号,后12位是主机号
-
网络号:140.252.16.0
-
这个子网的IP地址范围:140.252.16.0-140.252.31.255(实际能使用的IP地址还要减2,因为主机号部分全零是网络号,全1是广播地址)
-
-
练习1:
-
IP地址:168.195.0.0需要划分出来27个子网,子网掩码是多少?
-
思路:首先这个IP地址能看出来是个B类的网段,10开头,接着14位网络号,后面16位都是主机号,它的子网掩码是255.255.0.0。前面16位我们不能改,但我们可以拿出主机号的一部分来做网络号,我们需要再划分27个子网,那么每个子网都需要子网的位来表示,27个子网需要5位,因为27转成二进制是11011,所以还需要在原基础上多5位网络位,那就是11111111 11111111 11111000 00000000,这就是子网掩码,转换成十进制是:255.255.248.0
-
-
练习2:
-
IP地址:168.195.0.0需要划分出来多个子网,每个子网需要连接700台设备。子网掩码是多少?
-
思路:700台设备每个都需要IP,都需要主机位来分配,700转换二进制后是1010111100,是一个十位二进制,所以,需要10位主机位,剩下的就是网络位,11111111 11111111 11111100 00000000,转成十进制就是255.255.252.0,这就是符合要求的子网掩码
-
-
4.3 NAT机制
-
我们现在使用的ip协议一般都是ipv4,也就是使用32位的二进制来表示ip地址,但是这样表示的ip地址是有限个的,最多只有2^32-1个,所以如果想要所有的设备都可以上网交流的话,这样是远远不够的
-
在向别的外网通信的时候,不使用局域网中的IP地址,而是使用它的外网地址.所有处于同一个局域网中的设备,在和外部进行交流的时候,都是使用的外网地址.对于我上面的例子来说,如果我的笔记本192.168.1.3想要和外网交流,那么不会直接使用此时的地址,而是要使用我们的供应商提供的外网地址103.57.12.60 。在不同的局域网之间,IP地址可以相同,但是在同一个局域网内,IP地址不可以相同。另外,外网之间可以任意的进行交流,局域网只有其内部可以互相交流。
4.4 路由机制
- 每一个路由器都有路由表,甚至我们的主机也都有,数据报根据路由表进行跳转的。路由器告诉我们就是它内部的网络。局域网内转发(ARP协议)。路由器告诉我们下一站去哪里。即报文的最终目的地路由器不知道,但是推荐了一个地方让我们去问。即报文转发给默认路由器。
5. ICMP协议
-
也是网络层协议,作用就是检测通信错误,如传输超时,主机关闭,线路拥塞,路由器错误等等,都会发送ICMP报文进行通知。
-
报文格式
6.FTP协议
6.1概念:
FTP文件传输协议,这是应用层的协议,基于传输层的TCP协议实现的。可以传文件或者下载文件。一般用于C/S架构的软件。
6.2工作流程:
-
客户端请求服务端的21号端口,建立连接
-
进行身份验证
-
客户端发送下载命令,服务端在20号端口创建一个TCP数据连接。
-
文件传输完成后,TCP断开连接,如果再有新数据需要传输,重新建立20号端口的连接。
-
FTP数据连接的两种模式:
-
被动模式(PASV模式)(客户端被动,因为它需要服务端告诉它去连接哪个端口)
-
当客户端在防火墙后面时,需要使用被动模式
-
客户端和服务端通过21号端口三次握手建立TCP连接
-
客户端通过刚才建立的控制连接通道,发送PASV数据连接的命令,服务器会启动对20号端口的监听,并且返回信息告诉客户端:你可以跟20号端口建立数据连接。
-
客户端主动跟服务端的20号端口建立数据连接,传输数据。
-
-
主动模式(PORT模式)(这时候客户端是主动的,可以指定让服务端连接自己的哪个端口,此时没有防火墙,所以服务端可以连接客户端的端口)
-
客户端通过三次握手跟服务端21号端口建立控制连接
-
客户端主动在端口B创建监听,并通过21端口的控制连接通道告知服务端你可以跟我的B端口建立连接。这个告知命令是PORT。
-
服务器通过20端口跟客户端的B端口建立数据连接,传输数据。
-
-
7.WebSocket协议
7.1概念:
也是基于TCP协议的一种应用层协议,它最大的特点是全双工通信。实现了客户端和服务器之间的全双工,客户端既可以主动发消息给服务端,(HTTP协议服务端是被动的,不能主动跟客户端通信,只能去响应客户端的请求),服务端也可以主动发消息给客户端。
7.2HTTP的不足:
- 如果服务端的资源频繁更新,作为客户端想要及时地了解最新的资源,就必须不断发请求得到服务端的响应。通常我们会用ajax这种异步加载的方式来不断给服务端发消息,反复询问资源是否更新。这个反复问的过程可以叫轮询。如果长时间没有更新,这样对服务器和网络都会造成无意义的消耗。问的频率越高消耗越大,问的频率低了,就可能错过更新。
7.3WebSocket全双工通信
-
HTTP是单工通信,WebSocket是全双工双向通信,通信的每一方都可以主动跟对方联系。所以针对上面这个问题,就可以很好解决。只要服务器的资源有更新,它就可以主动告知客户端,客户端就不需要轮询了,节省了资源。
8.Socket不是协议
-
Socket是套接字,不是协议,是为了方便使用传输协议(TCP\UDP)而封装出来的一组接口API,它位于应用层和传输层之间。
-
套接字(Socket)是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。它是网络通信的基石,是支持TCP/IP协议的路通信的基本操作单元。套接字可以看作不同主机间的进程进行双间通信的端点,它构成了单个主机内及整个网络间的编程界面。
套接字存在于通信域中,通信域是为了处理一般的线程通过套接字通信而引进的一种抽象概念。套接字通常和同一个域中的套接字交换数据,数据交换也可能穿越域的界限,但这时一定要执行某种解释程序。各种进程使用这个相同的域互相之间用Internet协议簇来进行通信。
套接字可以分为三种类型:流式套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)。流式套接字提供面向连接、可靠的数据传输服务,数据无差错、无重复发送且按发送顺序接收。数据报套接字提供无连接服务,数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。原始套接字允许对较低层次协议如IP、ICMP进行直接访问,它功能强大但使用较为不便,主要用于一些协议的开发。
进行通信。
套接字可以分为三种类型:流式套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)和原始套接字(SOCK_RAW)。流式套接字提供面向连接、可靠的数据传输服务,数据无差错、无重复发送且按发送顺序接收。数据报套接字提供无连接服务,数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或重复,顺序发送,可能乱序接收。原始套接字允许对较低层次协议如IP、ICMP进行直接访问,它功能强大但使用较为不便,主要用于一些协议的开发。
在C++中,可以使用套接字进行网络通信编程。通过创建套接字、绑定地址和端口、监听连接、接受连接、发送和接收数据等操作,可以实现多个客户端向一个服务端发送消息的功能。套接字编程需要掌握网络编程的基本概念和技能,包括IP地址、端口号、TCP/IP协议等。同时,还需要熟悉C++语言的相关语法和库函数,如socket()、bind()、listen()、accept()、send()、recv()等。