谈谈对HTTP、TCP、IP、socket协议的理解
一、计算机网络分层及作用
net.png- 物理层:透明的传输比特流
- 数据链路层:简历逻辑链接、进行硬件地址寻址、差错效验等功能
- 网络层:进行逻辑地址寻址,实现不同网络之间的路径选择
- 传输层:定义传输数据的协议端口号,以及流控和差错效验
- 会话层:建立、管理、终止会话。(在五层模型中已经合并到了应用层)对应主机进程,指本地主机与远程主机正在进行的会话
- 表示层:数据的表示、安全、压缩。(在五层模型中已经合并到了应用层)
- 应用层:网络服务于最终用户的一个接口
二、 HTTP
超文本传输协议(HTTP: HyperText Transfer Protocol)
HTTP
协议对应应用层,HTTP
是基于TCP
连接的。HTTP
连接就是所谓的短连接
,即客户端向服务器发送一次请求,服务器端响应后连接即会断掉。
HTTP 1.0
中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。
HTTP 1.1
中则可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。
因为HTTP
是“短连接”,所以要保持客户端程序的在线状态,需要不断的向服务器发起连接请求。一般的做法就是不需要获取任何数据,客户端也保持每隔一段固定时间向服务器发送一次“保持连接”的请求,服务器在收到该请求后对客户端进行回复,表示知道了客户端“在线”。若服务器长时间无法收到客户端的请求,则认为客户端“下线”了,若客户端长时间无法收到服务器的回复,则认为网络已经断开。
三、TCP/IP
TPC/IP
协议是传输层协议,主要解决数据如何在网络中传输。“IP”
代表网际协议,TCP
和UDP
使用该协议从一个网络传送数据包到另一个网络。把IP
想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP
和UDP
是高速公路上的“卡车”,它们携带的货物就是像HTTP
,文件传输协议FTP
这样的协议等。
应该能理解,TCP
和UDP
是FTP
,HTTP
和SMTP
之类使用的传输层协议。虽然TCP
和UDP
都是用来传输其他协议的,它们却有一个显著的不同:TCP
提供有保证的数据传输,而UDP
不提供。这意味着TCP有一个特殊的机制来确保数据安全的不出错的从一个端点传到另一个端点,而UDP不提供任何这样的保证
。
TCP 标志位,有以下6种标示:
1、SYN(synchronous建立联机)
2、ACK(acknowledgement 确认)
3、PSH(push传送)
4、FIN(finish结束)
5、RST(reset重置)
6、URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
客户端 TCP 状态迁移:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED
服务器TCP状态迁移:
CLOSED->LISTEN->SYN收到->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSED
各个状态的意义如下:
LISTEN - 侦听来自远方TCP端口的连接请求;
SYN-SENT -在发送连接请求后等待匹配的连接请求;
SYN-RECEIVED - 在收到和发送一个连接请求后等待对连接请求的确认;
ESTABLISHED- 代表一个打开的连接,数据可以传送给用户;
FIN-WAIT-1 - 等待远程TCP的连接中断请求,或先前的连接中断请求的确认;
FIN-WAIT-2 - 从远程TCP等待连接中断请求;
CLOSE-WAIT - 等待从本地用户发来的连接中断请求;
CLOSING -等待远程TCP对连接中断的确认;
LAST-ACK - 等待原来发向远程TCP的连接中断请求的确认;
TIME-WAIT -等待足够的时间以确保远程TCP接收到连接中断请求的确认;
CLOSED - 没有任何连接状态;
四、TCP/IP 三次握手四次挥手
三次握手四次挥手.jpg1、三次握手
第一次握手:建立连接时,客户端A发送SYN包(SYN=j)
到服务器B,并进入SYN_SEND
状态,等待服务器B确认。
第二次握手:服务器B收到SYN包
,必须确认客户A的SYN(ACK=j+1)
,同时自己也发送一个SYN包(SYN=k)
,即SYN+ACK
包,此时服务器B进入SYN_RECV
状态。
第三次握手:客户端A收到服务器B的SYN+ACK
包,向服务器B发送确认包ACK(ACK=k+1)
,此包发送完毕,客户端A和服务器B进入ESTABLISHED
状态,完成三次握手。 完成后,客户端和服务器开始传送数据。
2、四次挥手
由于TCP
连接是全双工
的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN
来终止这个方向的连接。收到一个 FIN
只意味着这一方向上没有数据流动,一个TCP
连接在收到一个FIN
后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
TCP
的连接的拆除需要发送四个包,因此称为四次挥手(four-way handshake)。客户端或服务器均可主动发起挥手动作,在socket
编程中,任何一方执行close()
操作即可产生挥手操作。
客户端A发送一个FIN
,用来关闭客户A到服务器B的数据传送。
服务器B收到这个FIN
,它发回一个ACK
,确认序号为收到的序号加1
。和SYN
一样,一个FIN
将占用一个序号。
服务器B关闭与客户端A的连接,发送一个FIN
给客户端A。
客户端A发回ACK
报文确认,并将确认序号设置为收到序号加1。
3、深入理解TCP连接的释放:
TCP
协议的连接是全双工
连接,一个TCP
连接存在双向的读写通道。
简单说来是“先关读,后关写”
,一共需要四个阶段。以客户机发起关闭连接为例:
1.服务器读通道关闭
2.客户机写通道关闭
3.客户机读通道关闭
4.服务器写通道关闭
关闭行为是在发起方数据发送完毕之后,给对方发出一个FIN(finish)
数据段。直到接收到对方发送的FIN
,且对方收到了接收确认ACK
之后,双方的数据通信完全结束,过程中每次接收都需要返回确认数据段ACK
。
详细过程:
第一阶段: 客户机发送完数据之后,向服务器发送一个FIN
数据段,序列号为i
;
1.服务器收到
FIN(i)
后,返回确认段ACK
,序列号为i+1
,关闭服务器读通道;
2.客户机收到ACK(i+1)
后,关闭客户机写通道;
(此时,客户机仍能通过读通道读取服务器的数据,服务器仍能通过写通道写数据)
第二阶段: 服务器发送完数据之后,向客户机发送一个FIN
数据段,序列号为j
;
3.客户机收到
FIN(j)
后,返回确认段ACK
,序列号为j+1
,关闭客户机读通道;
4.服务器收到ACK(j+1)
后,关闭服务器写通道。
这是标准的TCP
关闭两个阶段,服务器和客户机都可以发起关闭,完全对称。
FIN
标识是通过发送最后一块数据时设置的,标准的例子中,服务器还在发送数据,所以要等到发送完的时候,设置FIN
(此时可称为TCP
连接处于半关闭状态,因为数据仍可从被动关闭一方向主动关闭方传送)。如果在服务器收到FIN(i)
时,已经没有数据需要发送,可以在返回ACK(i+1)
的时候就设置FIN(j)
标识,这样就相当于可以合并第二步和第三步。
4、TCP的 TIME_WAIT 和 CLOSE_WAIT 状态
CLOSE_WAIT:
发起TCP
连接关闭的一方称为client
,被动关闭的一方称为server
。被动关闭端未发出FIN
的TCP
状态是CLOASE_WAIT
。出现这种状况一般都是由于server
端代码的问题,如果你的服务器上出现大量CLOSE_WAIT
,应该要考虑检查代码。
TIME_WAIT:
根据TCP
协议定义的3
次握手断开连接规定, 发起socket
主动关闭的一方 socket
将进入TIME_WAIT
状态。TIME_WAIT
状态将持续2
个MSL(Max Segment Lifetime)
,在Windows下默认为4分钟,即240秒。TIME_WAIT
状态下的socket
不能被回收使用. 具体现象是对于一个处理大量短连接的服务器,如果是由服务器主动关闭客户端的连接,将导致服务器端存在大量的处于TIME_WAIT
状态的socket
, 甚至比处于Established
状态下的socket
多的多,严重影响服务器的处理能力,甚至耗尽可用的socket
,停止服务。
五、socket
socket
连接就是所谓的长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉;但是由于各种环境因素可能会是连接断开,比如说:服务器端或客户端主机down了,网络故障,或者两者之间长时间没有数据传输,网络防火墙可能会断开该连接以释放网络资源。所以当一个socket
连接中没有数据的传输,那么为了维持连接需要发送心跳消息~~具体心跳消息格式是开发者自己定义的。
套接字(socket
)是通信的基石,是支持TCP/IP
协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP
地址,本地进程的协议端口,远地主机的IP
地址,远地进程的协议端口。
我们平时说的最多的socket
是什么呢,实际上socket
是对TCP/IP
协议的封装,Socket
本身并不是协议,而是一个调用接口(API),通过Socket
,我们才能使用TCP/IP
协议。 实际上,Socket
跟TCP/IP
协议没有必然的联系。Socket
编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket
的出现只是使得程序员更方便地使用TCP/IP
协议栈而已,是对TCP/IP
协议的抽象,从而形成了我们知道的一些最基本的函数接口,比如create、 listen、connect、accept、send、read
和write
等等。
网络有一段关于socket
和TCP/IP
协议关系的说法比较容易理解:
“TCP/IP
只是一个协议栈,就像操作系统的运行机制一样,必须要具体实现,同时还要提供对外的操作接口。这个就像操作系统会提供标准的编程接口,比如win32编程接口一样,TCP/IP
也要提供可供程序员做网络开发所用的接口,这就是Socket
编程接口。”
总结:
实际上,传输层的TCP
是基于网络层的IP
协议的,而应用层的HTTP
协议又是基于传输层的TCP
协议的,而Socket
本身不算是协议,就像上面所说,它只是提供了一个针对TCP
或者UDP
编程的接口, 你可以借助它建立TCP
连接等等。
而http
是个应用层的协议,它实际上也建立在TCP
协议之上(HTTP
是轿车,提供了封装或者显示数据的具体形式;Socket
是发动机,提供了网络通信的能力)。