扫码关注公众号
TCP三次握手中,accept函数是发生在TCP三次握手的那个阶段?
服务器端的listen函数:intlisten(intsockfd,intbacklog);其中sockfd是与某个服务绑定的套接口,backlog是允许阻塞的最大请求个数。在服务器端存在着两个队列,一个是已经通过三次握手“建立连接的队列“(FIFOwithestablishedstate)处于Established状态,另一个是“未完成连接的队列”(FIFOwithsyn_rcvdstate)处于SYN_RCVD状态。这两个队列的长度之和就是backlog。在服务器端的accept函数,相当于从“建立连接的队列”中取出一个来进行后续的数据交换。而三次握手是发生在connect函数中,connect函数执行成功就相当于已经建立三次握手。
如果TCP连接过程中,第三次握手失败怎么办?
server给client返回一个SYN+ACK报文后server进入SYN_RCV状态。client收到SYN+ACK报文后进入ESTABLISHED状态,并且给server返回一个ACK报文。server端发送了SYN+ACK报文后就会启动一个定时器,等待client返回的ACK报文。如果第三次握手失败的话client给server返回的ACK报文,在传输过程中出现故障,server并不能收到这个ACK报文。那么server端就会启动超时重传机制,超过规定时间后重新发送SYN+ACK,重传次数根据/proc/sys/net/ipv4/tcp_synack_retries来指定,默认是5次。如果重传指定次数到了后,仍然未收到ACK应答,那么一段时间后,server自动关闭这个连接。但是client认为这个连接已经建立,如果client端向server写数据,server端将以RST包响应,方能感知到server的错误。
如何保证TCP连接的可靠性?
TCP通过以下方式提供数据传输的可靠性:(1)TCP在传输数据之前,都会把要传输的数据分割成TCP认为最合适的报文段大小。在TCP三次我握手的前两次握手中(也就是两个SYN报文段中),通过一个“协商”的方式来告知对方自己期待收到的最大报文段长度(MSS),结果使用通信双发较小的MSS最为最终的MSS。在SYN=1的报文段中,会在报文段的选项部分来指定MSS大小(相当于告知对方自己所能接收的最大报文段长度)。在后续通信双发发送应用层数据之前,如果发送数据超过MSS,会对数据进行分段。(2)使用了超时重传机制。当发送一个TCP报文段后,发送发就会针对该发送的段启动一个定时器。如果在定时器规定时间内没有收到对该报文段的确认,发送方就认为发送的报文段丢失了要重新发送。(3)确认机制。当通信双发的某一端收到另一个端发来的一个报文段时,就会返回对该报文段的确认报文。(4)首部校验和。在TCP报文段首部中有16位的校验和字段,该字段用于校验整个TCP报文段(包括首部和数据部分)。IP数据报的首部校验和只对IP首部进行校验。TCP详细的校验过程如下,发送TCP报文段前求一个值放在校验位,接收端接受到数据后再求一个值,如果两次求值形同则说明传输过程中没有出错;如果两次求值不同,说明传输过程中发生错误,无条件丢弃该报文段引发超时重传。(5)使用滑动窗口流量控制协议。(6)由于在TCP发送端可能对数据分段,那么在接收端会对接收到的数据重新排序。