Computer Network
TCP/IP
为什么 ack=seq+1 而不是 ack=seq? 通过查询资料和所学内容,我们知道: 1. 三次握手的前两次握手,client和server会根据一定的算法(连接四元组和时间戳还有Security Number)生成ISS。 2. 三次握手的后两次握手,client和server分别会对对方发过来的SYN进行应答,在ack序列上等于seq+1。 3. 后面传输数据的时候,sender发送len长度的data,receiver就会将ack(receiver)=seq(sender)+len(sender)。
所以说,3中接收到多少数据就讲多少数据长度的len加在seq上是一个正常的行为,问题出在2的确认SYN中为什么将ack=seq+1,搜索到结果有如下几个: 1. SYN和FIN也是需要确认的信息,所以需要占据一个seq,表示该信息已经被确认,不需要重传。 2. 如果SYN和FIN不占据一个seq,对于FIN而言,四次挥手的第二三次server的挥手除了FLAG外其他其实是一样的,即一样的ack,可能也有一样的seq(没有数据需要传输的情况下),可能导致client段无法分辨第二次挥手的ACK和第三次挥手的FIN。
Notice that the acknowledgement number has been increased by 1 although no payload data has yet been sent by the client. This is because the presence of the SYN or FIN flag in a received packet triggers an increase of 1 in the sequence. (This does not interfere with the accounting of payload data, because packets with the SYN or FIN flag set do not carry a payload.)
注:收到的报文中只有ACK时不需要将seq+1。
TCP传输中ACK的优化 已经知道的有延迟ACK,还有就是ACK和需要传输的数据一起过去,SO上面已经有大佬画了图:
Before ACK Optimization: +-------------------------------------------------------+ | client network server | +-----------------+ +--------------------| | (connect) | ---- SYN ----> | | | | <-- SYN,ACK -- | (accepted) | | (connected) | ---- ACK ----> | | \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ when client sends... \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ | | | | | (send) | ---- data ---> | | | | <---- ACK ---- | (data received) | \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ when server sends... \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ | | | | | | <--- data ---- | (send) | | (data received) | ---- ACK ----> | | \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ ...and so on, til the connection is shut down or reset ========================================================= ========================================================= After ACK Optimization: \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/ | | | | | | <--- data ---- | (send) | | (data received) | | | | (send) | -- data,ACK -> | | | | | (data received) | | | <- data,ACK -- | (send) | | (data received) | | | | (wait a bit) | <--- data ---- | (send) | | (data received) | | | | (send) | -- data,ACK -> | | | | | (data received) | | (send) | ---- data ---> | (wait a bit) | | | | (data received) | | | <- data,ACK -- | (send) | | (data received) | | | | (wait a bit) | (dead air) | | | | ---- ACK ----> | | \_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
TCP Connection State Diagram in rfc793
+---------+ ---------\ active OPEN | CLOSED | \ ----------- +---------+<---------\ \ create TCB | ^ \ \ snd SYN passive OPEN | | CLOSE \ \ ------------ | | ---------- \ \ create TCB | | delete TCB \ \ V | \ \ +---------+ CLOSE | \ | LISTEN | ---------- | | +---------+ delete TCB | | rcv SYN | | SEND | | ----------- | | ------- | V +---------+ snd SYN,ACK / \ snd SYN +---------+ | |<----------------- ------------------>| | | SYN | rcv SYN | SYN | | RCVD |<-----------------------------------------------| SENT | | | snd ACK | | | |------------------ -------------------| | +---------+ rcv ACK of SYN \ / rcv SYN,ACK +---------+ | -------------- | | ----------- | x | | snd ACK | V V | CLOSE +---------+ | ------- | ESTAB | | snd FIN +---------+ | CLOSE | | rcv FIN V ------- | | ------- +---------+ snd FIN / \ snd ACK +---------+ | FIN |<----------------- ------------------>| CLOSE | | WAIT-1 |------------------ | WAIT | +---------+ rcv FIN \ +---------+ | rcv ACK of FIN ------- | CLOSE | | -------------- snd ACK | ------- | V x V snd FIN V +---------+ +---------+ +---------+ |FINWAIT-2| | CLOSING | | LAST-ACK| +---------+ +---------+ +---------+ | rcv ACK of FIN | rcv ACK of FIN | | rcv FIN -------------- | Timeout=2MSL -------------- | | ------- x V ------------ x V \ snd ACK +---------+delete TCB +---------+ ------------------------>|TIME WAIT|------------------>| CLOSED | +---------+ +---------+
Reference
Last updated
Was this helpful?