计算机网络知识积累

TCP可靠性

(1)序列号、确认应答、超时重传

数据到达接收方,接收方需要发出一个确认应答,表示已经收到该数据段,并且确认序号会说明了它下一次需要接收的数据序列号。如果发送迟迟未收到确认应答,那么可能是发送的数据丢失,也可能是确认应答丢失,这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间)+一个偏差值

(2)窗口控制与高速重发控制/快速重传

TCP会利用窗口控制来提高传输速度,即在一个窗口大小内,不用一定要等到应答才能发送下一段数据,窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制,每一个没收到确认应答的数据都要重发。使用窗口控制,发送端如果收到3次相同应答,就会立刻进行重发;但还有种情况有可能是数据都收到了,但是有的应答丢失了,这种情况不会进行重发,因为发送端知道,如果是数据段丢失,接收端不会放过它的,会疯狂向它提醒

(3)拥塞控制

如果把窗口定的很大,发送端连续发送大量的数据,可能会造成网络的拥堵,甚至造成网络的瘫痪。所以TCP在为了防止这种情况而进行了拥塞控制。

①慢启动

定义拥塞窗口,一开始将该窗口大小设为1,之后每次收到确认应答,将拥塞窗口大小*2

②拥塞避免

设置慢启动阈值,一般开始都设为65536。拥塞避免是指当拥塞窗口大小达到这个阈值,拥塞窗口的值不再指数上升,而是加法增加(每次确认应答,拥塞窗口大小+1),来避免拥塞

③快重传

在遇到3次重复确认应答时,代表收到了3个报文段,但是这之前的1个段丢失了,便对它进行立即重传。然后,先将阈值设为当前窗口大小的一半,然后将拥塞窗口大小设为慢启动阈值+3的大小

TCP建立连接和断开连接的过程

(1)序号和标志位

序列号seq:占四个字节,其为当前包的第一个序列号

确认号ack:占四个字节,为下一个包的第一个序列号

确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效

同步SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求的包。若同意连接,则在响应包中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求。SYN这个标志位只有在TCP建立连接时才会被置1,握手完成后SYN标志位被置0。

终止FIN:用来释放一个连接。FIN=1表示:此包的发送方的数据已经发送完毕,并要求释放运输连接

注意:ACK、SYN和FIN这些大写的单词表示标志位,其值要么是1,要么是0;ack、seq小写的单词表示序号

(2)三次握手

第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND(发送)状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV(接收)状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED(已建立)状态,完成三次握手。

(4)四次挥手

第一次挥手:客户端发送一个FIN,用来关闭客户端到服务器端的数据传送,也就是客户端告诉服务器端:我已经不会再给你发数据了(当然,在fin包之前发送出去的数据,如果没有收到对应的ack确认报文,客户端依然会重发这些数据),但是,此时客户端还可以接受数据。

第二次挥手:服务器收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1。

第三次挥手:服务器发送一个FIN,用来关闭服务器到客户端的数据传送,也就是告诉客户端,我的数据也发送完了,不会再给你发数据了。

第四次挥手:客户端收到FIN后,发送一个ACK给服务器,确认序号为收到序号+1,至此,完成四次挥手。

计算机网络知识积累_第1张图片

OSI七层模型和TCP/IP四层模型

计算机网络知识积累_第2张图片

(1)OSI

物理层: 通过媒介传输比特,确定机械及电气规范,传输单位为bit,主要包括的协议为:IEE802.3 CLOCK RJ45

数据链路层: 将比特组装成帧和点到点的传递,传输单位为帧,主要包括的协议为MAC VLAN PPP

网络层:负责数据包从源到宿的传递和网际互连,传输单位为包,主要包括的协议为IP ARP ICMP

传输层:提供端到端的可靠报文传递和错误恢复,传输单位为报文,主要包括的协议为TCP UDP

会话层:建立、管理和终止会话,传输单位为SPDU,主要包括的协议为RPC NFS

表示层: 对数据进行翻译、加密和压缩,传输单位为PPDU,主要包括的协议为JPEG ASII

应用层: 允许访问OSI环境的手段,传输单位为APDU,主要包括的协议为FTP HTTP DNS

(2)TCP/IP

①定义

TCP/IP是传输控制协议和网络协议的简称,它定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。

TCP/IP 不是一个协议,而是一个协议集合的统称,里面包括了 IP 协议、ICMP 协议、TCP 协议、以及 http、ftp、pop3、https 协议等。网络中的计算机都采用这套协议族进行互联。

②四层模型

应用层:应用程序通过这一层访问网络,常见 FTP、HTTP、DNS 和 TELNET 协议;

运输层:TCP 协议和 UDP 协议;     

网络层:IP 协议,IGMP 协议,ICMP 协议等; (都是I开头的,表示internet)    

网络接口层:是 TCP/IP 协议的基层,负责数据帧的发送和接收。(MAC,VLAN)

TCP与UDP区别

UDP(User Data Protocol)用户数据报协议

①无连接

②不可靠(不能保证都送达)

③面向包(UDP数据传输单位是报文,不会对数据进行拆分和拼接操作,只是给上层传来的数据加个UDP头或者给下层来的数据去掉UDP头)

④没有拥塞控制,始终以恒定速率发送数据

⑤支持一对一、一对多、多对多、多对一

⑥首部开销小,只有8字节

TCP(Transmission Control Protocol)传输控制协议

①有连接

②可靠的

③面向字节流

④全双工通信,TCP两端既可以作为发送端也可以作为接收端

⑤连接的两端只能是两个端点,即一对一,不能一对多

⑥至少20个字节,比UDP大的多

IP地址分类

IP地址是32位的二进制数值,用于在TCP/IP通讯协议中标记每台计算机的地址。通常我们使用点式十进制来表示,如192.168.0.5等等。每个IP地址又可分为两部分。即网络号部分和主机号部分:网络号表示其所属的网络段编号,主机号则表示该网段中该主机的地址编号。按照网络规模的大小,IP地址可以分为A、B、C、D、E五类。

ARP(地址解析协议)的工作原理

地址解析协议,即ARP(Address Resolution Protocol),是根据IP地址获取物理地址的一个TCP/IP协议。

1:首先,每个主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址之间的对应关系。

2:当源主机要发送数据时,首先检查ARP列表中是否有对应IP地址的目的主机的MAC地址,如果有,则直接发送数据,如果没有,就向本网段的所有主机发送ARP数据包,该数据包包括的内容有:源主机 IP地址,源主机MAC地址,目的主机的IP 地址

3:当本网络的所有主机收到该ARP数据包时,首先检查数据包中的IP地址是否是自己的IP地址,如果不是,则忽略该数据包,如果是,则首先从数据包中取出源主机的IP和MAC地址写入到ARP列表中,如果已经存在,则覆盖,然后将自己的MAC地址写入ARP响应包中,告诉源主机自己是它想要找的MAC地址。

4:源主机收到ARP响应包后。将目的主机的IP和MAC地址写入ARP列表,并利用此信息发送数据。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。

注意:广播(255.255.255.255)发送ARP请求,单播发送ARP响应。

DNS(域名系统)的工作流程

DNS是应用层协议,事实上他是为其他应用层协议工作的,包括不限于HTTP和SMTP以及FTP,用于将用户提供的主机名解析为IP地址。DNS域名解析过程:其中本地域名服务器往往会有高速缓存,实现域名的快速查找(DNS是基于UDP协议实现的,追求解析速度)

计算机网络知识积累_第3张图片

HTTP

(1)定义

HTTP是超文本传输协议,它是TCP/IP协议的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程

(2)协议的请求/响应的步骤

①客户端连接到Web服务器

一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。例如百度

②发送HTTP请求

通过TCP套接字,客户端向Web服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行和请求数据4部分组成。

③服务器接受请求并返回HTTP响应

Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行和响应数据4部分组成。

④释放连接TCP连接

若connection 模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求

⑤客户端浏览器解析HTML内容

客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示

(3)返回码

HTTP协议的响应报文由状态行、响应头部和响应包体组成,其响应状态码总体描述如下:

①1xx:指示信息--表示请求已接收,继续处理。

②2xx:成功--表示请求已被成功接收、理解、接受。

③3xx:重定向--要完成请求必须进行更进一步的操作。

④4xx:客户端错误--请求有语法错误或请求无法实现。

⑤5xx:服务器端错误--服务器未能实现合法的请求。

(4)在浏览器地址栏键入URL,按下回车之后会经历以下流程:

①浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;

②解析出 IP 地址后,根据该 IP 地址和默认端口80,和服务器建立TCP连接;

③浏览器发出读取文件(URL中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;

④服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器;

⑤释放 TCP连接;

⑥浏览器将该 html 文本并显示内容;

HTTPS

(1)定义

HTTPS是一种应用层协议,本质上来说它是HTTP协议的一种变种。HTTPS比HTTP协议安全,因为HTTP是明文传输,而HTTPS是加密传输,加密过程中使用了三种加密手段,分别是证书,对称加密和非对称加密。HTTPS相比于HTTP多了一层SSL/TSL,其构造如下:

计算机网络知识积累_第4张图片

(2)加密算法

①证书加密

服务器在使用证书加密之前需要去证书颁发机构申请该服务器的证书,在HTTPS的请求过程服务器端将会把本服务器的证书发送给客户端,客户端进行证书验证,以此来验证服务器的身份

②对称加密

HTTPS的请求中,客户端和服务器之间的通信的数据是通过对称加密算法进行加密的。对称加密,即在加密和解密的过程使用同一个私钥进行加密以及解密,而且对称加密算法是公开的,所以该私钥是不能够泄漏的,因为私钥是需要在网络中进行传输的。流程:在A端生成私钥,传递给B端(传递过程需要是安全的),后面A端使用该私钥加密,传递数据报文到B端,B端使用接受到的私钥解密

加密过程:加密算法+明文+私钥------》密文

解密过程:解密算法+密文+私钥------》明文

适用场景:上述过程是不复杂的,对大量数据进行加密时,对称加密是适用的,速度快

③非对称加密算法

HTTPS的请求中也使用了非对称加密算法。非对称加密,加密和解密过程使用不同的密钥,一个公钥,对外公开,一个私钥,仅是解密端拥有。由于公钥和私钥是分开的,非对称加密算法安全级别高,加密密文长度有限制,适用于对少量数据进行加密,速度较慢。

case1:使用公钥加密,私钥解密

加密过程:加密算法+明文+共钥------》密文

解密过程:解密算法+密文+私钥------》明文

case2:使用私钥加密,公钥解密

加密过程:加密算法+明文+私钥------》密文

解密过程:解密算法+密文+共钥------》明文

(3)详细过程

1.客户端想服务器发起HTTPS的请求,连接到服务器的443端口;

2.服务器将非对称加密的公钥传递给客户端,以证书的形式回传到客户端

3.服务器接受到该公钥进行验证,就是验证2中证书,如果有问题,则HTTPS请求无法继续;如果没有问题,则上述公钥是合格的。(第一次HTTP请求)客户端这个时候随机生成一个私钥,成为client key,客户端私钥,用于对称加密数据的。使用前面的公钥对client key进行非对称加密;

4.进行二次HTTP请求,将加密之后的client key传递给服务器;

5.服务器使用私钥进行解密,得到client key,使用client key对数据进行对称加密

6.将对称加密的数据传递给客户端,客户端使用非对称解密,得到服务器发送的数据,完成第二次HTTP请求。

计算机网络知识积累_第5张图片

(4)HTTPS优点

HTTPS传输数据过程中使用密钥进行加密,所以安全性更高

HTTPS协议可以认证用户和服务器,确保数据发送到正确的用户和服务器

(5)HTTPS缺点

HTTPS握手阶段延时较高:

因为进行HTTP会话之前还需要进行SSL握手

HTTPS部署成本高:

①HTTPS协议需要使用证书来验证自身的安全性,所以需要购买CA证书;

②由于采用HTTPS协议需要进行加解密的计算,占用CPU资源较多,需要的服务器配置或数目高

(6)HTTPS和HTTP的区别

①HTTPS是密文传输,HTTP是明文传输;

②默认连接的端口号是不同的,HTTPS是443端口,而HTTP是80端口;

②HTTPS在TCP三次握手阶段之后,还需要进行SSL的握手过程,协商加密使用的对称加密密钥

③HTTPS协议需要服务端申请证书,浏览器端安装对应的根证书

IP地址作用和MAC地址

(1)IP地址

IP地址是IP协议提供的一种统一的地址格式,为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。

(2)MAC地址

MAC地址是一个硬件地址,用来定义网络设备的位置,主要由数据链路层负责

报文区分

根据端口区分;看ip头中的协议标识字段,17是udp,6是tcp

粘包和拆包

(1)粘包

粘包是在客户端频繁发送数据量少的消息,则TCP不会在你发送一条信息的时候立刻发送到服务器端,而是等待多条消息,结合成一个包,然后一起发给服务器端。则此时服务器端会同时收到多条消息。(频繁发送到服务器端会耗费更多性能,TCP为了解决性能问题而产生的粘包问题)

(2)拆包

分包是在客户端发送一条数据量很大的消息,则TCP会将这条消息分成多个包,分别发送到服务器端。因此会导致服务器端接收到的消息不是完整的消息。(TCP防止发送数据量过大的信息丢失而重新发送导致的时间浪费而产生分包问题)

(3)粘包和拆包发生的原因

1、要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包。

2、待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。

3、要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包。

4、接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包。

等等

(4)解决方法

1、发送端给每个数据包添加包首部,首部中应该至少包含数据包的长度,这样接收端在接收到数据后,通过读取包首部的长度字段,便知道每一个数据包的实际长度了。

2、发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从接收缓冲区中读取固定长度的数据就自然而然的把每个数据包拆分开来。

3、可以在数据包之间设置边界,如添加特殊符号,这样,接收端通过这个边界就可以将不同的数据包拆分开

GET和POST的区别

(1)概括

GET请求:浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

POST请求:浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应(返回数据)

(2)区别:

①get参数通过url传递,post放在request body中。

②get请求在url中传递的参数是有长度限制的,而post没有。

③get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。

④get请求只能进行url编码,而post支持多种编码方式。

⑤get请求会浏览器主动cache,而post支持多种编码方式。

⑥get请求参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。

⑦GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

⑧GET产生一个TCP数据包;POST产生两个TCP数据包。

socket编程中服务器端和客户端主要用到哪些函数

(1)基于TCP的socket

①服务器端程序:

  • 创建一个socket,用函数socket()

  • 绑定IP地址、端口等信息到socket上,用函数bind()

  • 设置允许的最大连接数,用函数listen()

  • 接收客户端上来的连接,用函数accept()

  • 收发数据,用函数send()和recv(),或者read()和write()

  • 关闭网络连接

②客户端程序

  • 创建一个socket,用函数socket()

  • 设置要连接的对方的IP地址和端口等属性

  • 连接服务器,用函数connect()

  • 收发数据,用函数send()和recv(),或read()和write()

  • 关闭网络连接

计算机网络知识积累_第6张图片

(2)基于UDP的socket

①服务器端流程

  • 建立套接字文件描述符,使用函数socket(),生成套接字文件描述符。

  • 设置服务器地址和侦听端口,初始化要绑定的网络地址结构。

  • 绑定侦听端口,使用bind()函数,将套接字文件描述符和一个地址类型变量进行绑定。

  • 接收客户端的数据,使用recvfrom()函数接收客户端的网络数据。

  • 向客户端发送数据,使用sendto()函数向服务器主机发送数据。

  • 关闭套接字,使用close()函数释放资源。UDP协议的客户端流程

②客户端流程

  • 建立套接字文件描述符,socket()。

  • 设置服务器地址和端口,struct sockaddr。

  • 向服务器发送数据,sendto()。

  • 接收服务器的数据,recvfrom()。

  • 关闭套接字,close()。

计算机网络知识积累_第7张图片

阻塞,非阻塞,同步,异步

(1)阻塞

调用者在事件没有发生的时候,一直在等待事件发生,不能去处理别的任务

(2)非阻塞

调用者在事件没有发生的时候,可以去处理别的任务

(3)同步

调用者必须循环自去查看事件有没有发生

(4)异步

调用者不用自己去查看事件有没有发生,而是等待着注册在事件上的回调函数通知自己

socket连接

① 端口只是一个数字辨识,不是真正的物理端口;

②一个Socket连接的主键(即不同socket之间的区分)是由一个五元组{SRC-IP, SRC-PORT, DEST-IP, DEST-PORT, PROTOCOL}组成,即{源地址,源端口,目标地址,目标端口,协议}组成,那些说四元组不包含协议的说法是错误的。

③一个进程可以拥有多个socket连接。

若服务器能识别收到的请求与哪个socket有关(只要五元组不同),则可连接

①IP不同,端口号相同

②IP相同,端口号不同

③不同进程,端口号相同

④同一个进程,使用不同协议,可监听同一个端口号

多个客户端与服务器端链接

①使用多线程,每一个客户端对应一个线程

②客户端连接数量过多,可采用线程池

(1)服务器端

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace SocketServer
{
    class Program
    {
        static void Main(string[] args)
        {
            //服务器端
            Socket sktltn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sktltn.Bind(new IPEndPoint(IPAddress.Any, 12345));
            sktltn.Listen(30);
            while (true)
            {
                Socket sk = sktltn.Accept();
                //ThreadPool.SetMaxThreads(10, 10);
                ThreadPool.QueueUserWorkItem(p =>
                {
                    Socket skc = (Socket)sk;
                    byte[] array = new byte[10240];
                    int offset = 0;
                    while (true)
                    {
                        int len = skc.Receive(array, offset, array.Length - offset, SocketFlags.None);
                        if (len == 0)
                        {
                            break;
                        }
                        offset += len;
                    }
                    string content = Encoding.UTF8.GetString(array, 0, offset);
                    Console.WriteLine("> " + content);
                }, sk);
            }
        }
    }
}

(2)客户端

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace SocketClient
{
    class Program
    {
        static void Main(string[] args)
        {
            //客户端
            Console.WriteLine("输入文字,回车发送");
            while (true)
            {
                string str = Console.ReadLine();
                if (str.Length > 0)
                {
                    Socket sktc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    sktc.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 12345));
                    byte[] bytes = Encoding.UTF8.GetBytes(str);
                    int offset = 0;
                    while ((offset += sktc.Send(bytes, offset, bytes.Length - offset, SocketFlags.None)) < bytes.Length) ;
                    sktc.Close();
                }
            }
        }
    }
}

面试题

(1)为什么连接的时候是三次握手,关闭的时候却是四次挥手?

三次握手时,当服务器收到客户端发送的连接请求时,可以直接发送SYN+ACK的包,而四次挥手时,当服务器收到FIN包时,很可能并不会立即关闭socket,会先回复一个ACK包,告诉客户端,"你发的FIN包我收到了"。只有等到服务器所有的包都发送完了,服务器才能发送FIN报文,因此不能一起发送。

(2)为什么客户端第四次挥手后TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

因为最后一个ACK包可能会丢失,所以TIME_WAIT状态就是用来重发可能丢失的ACK包。若丢失,则服务器端没有收到ACK包,会不断重复的发送FIN包,所以客户端不能立即关闭,必须确认服务器收到ACK包。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。(2MSL是两倍的MSL,MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。)如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

(3)为什么不能只用两次握手?

3次握手完成功能:

①双方做好发送数据的准备工作

②允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

③防止已失效的连接请求又传送到服务器端,因而产生错误,从而造成的资源浪费

为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误

客户端发送的第一个链接请求S1由于某种原因,导致传送到服务器端时间相当久。这段时间客户端没有收到服务器端对S1的确认,就发送第二个链接请求S2,这时服务器端收到了,两者建立连接。但是S1发送到了服务器端,此时服务器端就发送确认,但是客户端已经清除了A1,所以丢弃了服务器端发来的确认。这时服务器端发来的消息都会被客户端丢弃,因为客户端没有发起这个链接请求

(4)为什么四次挥手中一般是客户端先关闭?

socket编程中客户端一般不需要绑定,而服务器端一般都要绑定,如果先结束服务器端则是服务器端先进行挥手操作,那么服务器端从TIME_WAIT到CLOSED状态则需要2MSL。这段时间服务器端绑定的端口号被占用了,套接字不会释放。所以这段时间重启了服务器之后,会出现绑定失败的错误

你可能感兴趣的:(计算机网络,网络)