http 的三次握手,首先客户端先进行一个connect连接,然后会发送一个SYN到客户端,紧接着自身的状态变为了SYN_SEND。服务段收到后,会将当前的连接放到一个半连接队列,并且返回给客户端一个ACK+SYN(服务段自身的SYN)。客户端收到服务的ACK,后证明服务端的接受能力和发送能力都没问题,然后客户端再发送一个ACK,证明能够收到服务端的信息,并且将自身的状态转为ESTABLISHED。然后服务端收到后,将该连接从半连接队列转到全连接队列。没有直接用,是因为服务端的处理能力是有限的,假如客户端连接很多,可能会accept不过来,将其放入队列能够进行缓冲。
**注意:**三次握手的主要目的是确保连接是双工的,可靠的通过更多的重传机制来保证连接
三次握手,建立TCP连接需要客户端和服务端总共至少发送三个包确认连接。
TCP三次握手流程图
-客户端发送一个TCP的SYN标志位置1的包指明发送的服务器端口,以及初始化序号 X
-服务器返回确认包ACK应答,及SYN标志位和ACK标志位均为1,同时将确认序号设置为 X+1
-客户端再次发送确认(ACK) SYN标志为0,ACK标志为1,并把服务器发送过来的ACK序号字段+1
第一次握手: 客户端什么都不确定。服务端确认对方发送正常。 第二次握手: 客户端发送/接受正常,对方发送接收正常。服务端确认自己发送正常,客户端发送正常。 第三次握手: 客户端发送/接受正常,服务端发送接受正常。服务端确认自己发送/接受正常,客户端发送接受正常。
阻塞后会发生
当网络原因服务端没有收到客户端的请求,且没有给客户端反馈。超时后客户端会再次向服务端发送请求。当网络畅通后服务器段收到最开始的请求并反馈给客户端。导致客户端认为自己未发送这个请求,服务端认为自己发送了一个新的请求,导致服务端性能浪费。
很多情况下,需要服务器端主动向客户端推送数据,保持客户端与服务器数据的实时与同步。此时若双方建立的是Socket连接,服务器就可以直接将数据传送给客户端;若双方建立的是HTTP连接,则服务器需要等到客户端发送一次请求后才能将数据传回给客户端,因此,客户端定时向服务器端发送连接请求,不仅可以保持在线,同时也是在“询问”服务器是否有新的数据,如果有就将数据传给客户端。
服务器将数据返回给客户端,客户端读取数据,显示在界面上
client和server的握手过程在我看来就像客人要到大户人家进行拜访。
首先,客人(client)跟主人家(server)发送请求拜访的邮件(syn)。主人家的管家把拜访请求记录到小本本上(syns quene),然后给客人回复了一封邀请函(syn + ack)。最后客人带着邀请函(ack)去拜访,管家根据邀请函才让客人进入家里(accept queue)做客。