网上关于tcp建立通信的文章已经很多,这里简要讲讲在客户端如何灵活运用tcp连接。
http和tcp
Http协议是建立在TCP协议基础之上的。从2.1中我们知道tcp是传输层的工作,http是应用层的工作。每次通信我们都必须建立tcp的连接。结束通信之后关闭tcp的连接。假设我们对一个服务端有512个请求,如果每次请求都进行打开关闭那有512次的操作,这就比较浪费资源了,最好的方式是1次握手,完成512次的请求,最好一次执行关闭。节约了中间511的握手和挥手操作。
3次挥手的情况
传统的tcp挥手是4次,但如果服务端可以立即关闭当前连接的话,4次挥手可以合并为3次。及第二次和第三次合并。
tcp的4种发送报文
报文 | 说明 |
---|---|
SYNC | 连接请求或连接接受报文 |
ACK | 确认收包 |
FIN | 此报文段的发送方的数据已经发送完毕,并要求释放连接 |
RST | 重置 |
tcp的11中状态
状态 | 说明 | 状态方 |
---|---|---|
LISTEN | 服务端开启端口,但无连接 | 服务端 |
SYNC-RCVD | 收到客户端SYNC报文,并回复SYNC+ACK后的状态 | 服务端 |
ESTABLISED | TCP3次握手后建立连接 | 服务端+客户端 |
CLOSE_WAIT | 服务端收到客户端FIN后的状态 | 服务端 |
LAST_ACK | 服务端进入CLOSE_WAIT后,释放资源,并通知客户端可以关闭后 | 服务端 |
CLOSE | 收到客户端关闭ACK后,服务器关闭端口 | 服务端+客户端 |
SYNC-SEND | 发送SYNC后,收到服务端SYNC+ACK前状态 | 客户端 |
FIN-WAIT-1 | 向服务端发送FIN后,收到服务端应答ACK前 | 客户端 |
FIN-WAIT-2 | 向服务端发送FIN并收到服务端第一次ACK后,第二次的FIN+ACK前 | 客户端 |
CLOSING | 位置和FIN-WAIT-2重叠,向服务端发送FIN并收到服务端第一次ACK后,还向服务器发送ACK | 客户端 |
TIME-WAIT | 向服务器发送第四次挥手ACK后,等待2MSL(Max Segment Lifetime)时的状态(防止ACK丢失,丢失后可以重发) | 客户端 |
httpclient如何实现连接的保持
httpclient使用连接池来存放未关闭的tcp连接。如果程序要使用连接则从连接池中借出连接,使用完之后归还连接给连接池。等客户端全部使用完调用close关闭tcp连接。但在使用的过程中,如果不注意会产生死锁,或者过早关闭tcp连接,关于如何使用连接池请看 4.1 连接池的正确使用
网友评论