文章目录
1、三次握手
1.1connect()、listen()和accept()三者之间的关系
在我之前的一篇博文中就有详细的提到过TCP的编程流程TCP详解及编程流程。在那篇博文中我们就详细提到了connect()、listen()和accept()这三个函数的使用。并且我们了解到了,连接的建立是在listen()之后accept之前
。
那么,具体的他们这三个函数内部的关系是怎样的呢?
1、connect()函数分析
【功能】
客户端主动连接服务器,建立连接是通过三次握手。
【注意】
- 这个连接的过程是内核完成的,不是这个函数完成的,这个函数的作用仅仅是通知给linux内核,让linux内核自动完成TCP三次握手连接
- 通常情况下,客户端的connect()函数会默认一直阻塞,直到三次握手成功或超市失败才返回
2、listen函数分析
【功能】
将该套接字和套接字对应的连接队列长度告诉linux内核。因此,可以看出,只要TCP服务器调用了listen(),客户端就可以通过connect()和服务器建立连接,而这个连接的过程是内核完成的
【注意】
- listen()函数不会阻塞
- 在被动状态的socket有两个队列,一个是正在进行三次握手的socket队列,一个是完成三次握手的socket队列。在握手完成后会从正在握手队列移到握手完成的队列,此时已经建立连接。
3、accept()函数分析
【功能】
从连接队列头部取出一个已经完成的连接,如果这个队列没有已经完成的连接,accept()函数就会阻塞,直到取出队列中已完成的用户连接为止。
1.1三次握手的过程
在 TCP/IP 协议中,TCP 协议提供可靠的连接服务,采用三次握手建立一个连接。因为TCP连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户,而而被动等待连接建立的应用进程叫做服务器。
用三次握手建立TCP连接的流程图如下:
第一次握手:
客户端执行connect函数,向服务器发送连接请求报文段,这时TCP报文首部的同步位SYN=1.这时==客户端进入SYN_SENT(同步已发送)==状态,等待服务器的确认
第二次握手:
服务器收到请求报文段后,如果同意建立连接,则向A发送确认,在确认报文段中SYN=1,ACK=1。这时服务器就进入了SYN_RCVD(同步收到)状态客户端进入ESTABLISHED状态
第三次握手:
客户端在收到服务器的确认过后,还要给服务器给出确认,确认报文段将ACK置1.TCP连接已经建立服务器都进入ESTABLISHED状态。完成三次握手,随后客户端与服务器之间就可以传输数据了。
三次握手的结果就是服务器知道了客户端发送数据的序列号,客户端也知道了服务器发送数据的序列号,并且双方都知道彼此知道了。
1.2三次握手的状态转换和安全问题
1、状态类型:
1、半连接状态:
发生在TCP三次握手过程中,客户端向服务器发起连接,服务器也进行了回应,但是客户端却不进行第三次握手
2、半打开状态
:在TCP连接中,如果某一端异常关闭,则该连接处于半打开状态。
3、半关闭状态
:当TCP链接中客户端向服务器发送 FIN 请求关闭,服务端回应ACK之后,并没有立即发送 FIN 给客户端,客户端就处于半关闭状态,此时客户端可以接收服务器发送的数据,但是客户端已经不能再向服务器发送数据。