计算机网络基础部分
TCP概述
TCP是面向连接的通信协议,通过三次握手建立连接才能开始数据的读写,通讯完成时要断开连接,由于TCP是面向连接的,所以只能用于端对端的通讯。
TCP提供的是一种可靠的数据流服务,数据有可能被拆分后发送,那么采用超时重传机制和应答确认机制是组成TCP可靠传输的关键设计。
在超时重传机制里面有个很重要的指标—重传超时的时间限定。网络环境并不是人为可以控制的,有时网络十分顺畅,有时有十分的卡顿,那么这个时间限定如果设置为一个固定值,是不科学不合理的,这样就需要根据网络环境等因素动态的调整这个值,那么就需要采样统计一个数据包从客服端到服务端往返一次的时长,这个时长就是RTT(round-trip time),然后根据这个时长通过各种算法和公式计算,最后确定重传超时值。
数据在网络中进行传输时,是不能确保所有的数据都在同一条线路中传输的,每个数据都有可能走得不同的线路到达目的地,由此可知,IP层进行数据传输时,是不能保证数据包按照发送的顺序达到目的机器。当IP层把它们向上传给TCP层后,TCP将包排序病进行错误检查。TCP数据包中包含序号和确认,所以未按照顺序接收到的包可以被排序,而损坏的包可以被重传。
TCP还采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。同时,TCP是全双工的,也就是连接的双方可以同时点对点的发送信息。
TCP三次握手(面试常客)
为什么需要三次握手?(面试常客)
TCP 是可靠的传输控制协议,而三次握手是保证数据可靠传输又能提高传输效率的最小次数。为什么?RFC793,也就是 TCP 的协议 RFC 中就谈到了原因,这是因为:
为了实现可靠数据传输, TCP 协议的通信双方,都必须维护一个序列号, 以标识发送出去的数据包中,哪些是已经被对方收到的。
举例说明:发送方在发送数据包时, 同时送上一个序号( 假设 为 100),那么接收方收到这个数据包以后, 就可以回复一个确认号(110 = 100 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 111 开始” 。
三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤。
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。
至于为什么不是四次,很明显,三次握手后,通信的双方都已经知道了对方序列号起始值,也确认了对方知道自己序列号起始值,第四次握手已经毫无必要了。
TCP四次挥手(面试常客)
为什么需要四次挥手(面试常客)
TCP 是全双工的连接,必须两端同时关闭连接,连接才算真正关闭。
如果一方已经准备关闭写,但是它还可以读另一方发送的数据。A方发送 FIN 结束报文给B方,B方收到后,回复 ACK 报文。当B方也已经写完了准备关闭,发送 FIN 报文,A方回 复 ACK。两端都关闭,TCP 连接正常关闭。
为什么需要TIME-WAIT状态(面试常客)
TCP是面向连接的通信协议,是一种可靠的数据流服务,需要TIME-WAIT状态的原因主要有两点:
1.可靠的终止TCP连接。
2.保证让迟来的TCP报文有足够的时间被识别并丢弃。
第一点的解释:根据前面的四次握手的描述,我们知道,客户端收到服务器的连接释放的FIN报文后,必须发出确认。如最后这个ACK确认报文丢失,那么服务器在规定时间内没有收到这个ACK确认报文,就要重发FIN连接释放报文,客户端因为有了这个TIME-WAIT状态所以并没有关闭,此时会重新发出确认报文ACK并重置TIME-WAIT倒计时,如此循环,直到服务器收到了客户端发来的确认报文ACK,服务器端才会关闭,而客户端在TIME-WAIT状态结束如果没有重新收到服务端发来的FIN报文,此时才能关闭,整个TCP连接才算终止连接。
第二点的解释:在Linux系统上,一个TCP端口不能被同时打开多次(也就是我们常见的端口占用),当一个 TCP 连接处于 TIME_WAIT状态时会继续占用该连接的端口,我们无法使用该端口来建立一个新连接。反过来思考,如果不存在 TIME_WAIT状态,则应用程序能过立即建立一个和刚关闭的连接相似的连接(这里的相似,是指他们具有相同的 IP 地址和端口号)。这个新的连接和原来相似的连接被称为原来连接的化身。新的化身可能受到属于原来连接携带应用程序数据的 TCP 报文段(迟到的报文段),这显然是不该发生的。这是 TIME_WAIT 状态存在的第二个原因。
TCP和UDP(面试常客)
TCP 和 UDP 都是传输层的协议,传输层主要为两台主机上的应用程序提供端到端的通信。
TCP 和 UDP 最不同的地方是,TCP 提供了一种可靠的数据传输服务,TCP 是面向连接的,也就是说,利用 TCP 通信的两台主机首先要经历一个建立连接的过程,等到连接建立后才开始传输数据,而且传输过程中采用“带重传的确认”技术来实现传输的可靠性。TCP 还采用一种称为“滑动窗口”的方式进行流量控制,发送完成后还会关闭连接。所以 TCP 要比UDP 可靠的多。
UDP(User Datagram Protocol 的简称, 中文名是用户数据报协议)是把数据直接发出去,而不管对方是不是在接收,也不管对方是否能接收的了,也不需要接收方确认,属于不可靠的传输,可能会出现丢包现象。
HTTP
一次完整的HTTP请求过程(面试常客)
- 进行 DNS 域名解析
- 三次握手建立 TCP 连接
- 客户端发起 HTTP 请求
- 服务器响应HTTP请求
- 客户端解析html代码,并请求html代码中的资源
- 客户端渲染展示内容
- 关闭 TCP 连接
一般情况下,一旦服务器向客户端返回了请求数据,它就要关闭TCP连接,但如果客户端或者服务器在其头信息加入keep-alive,TCP连接在发送后将仍然保持打开状态,于是,客户端可以继续通过相同的连接发送请求,也就是3到6这几个步骤,可以反复进行。
HTTP响应报文状态码
状态码类型 | 状态码意义 | |
---|---|---|
1xx | 信息性状态码 | 接收的请求正在处理 |
2xx | 成功状态码 | 请求正常处理完毕 |
3xx | 重定向状态码 | 需要采取进一步的操作来完成请求 |
4xx | 客户端错误状态码 | 服务器无法处理,客户端错误 |
5xx | 服务器错误状态码 | 服务器处理出错 |