自己动手学TCP/IP--TCP连接三次握手

TCP是面向连接的协议,面向连接的意思就是在连接的基础上实现数据的传输。TCP面向连接保证了它在通

信过程中的可靠性。

TCP头部是20个字节,详细的报文格式和各个字段的解释可以看下面:

在TCP通信之前,建立连接的过程被称为三次握手,下面是wireshark抓出来的图。

1.第一次握手:客户端发送SYN标志,序列号seq(随机生成,图中序列号是0是wireshark做了相对处理),

源端口随机生成,目标端口5000(程序决定),

头长度40字节是因为包含了可选字段。

2.第二次握手:服务端发回客户端,ACK标识同意接收连接,此时从客户端到服务端单向连接建立,SYN标

识服务端向客户端建立连接,同时标识了序列号(同上)对于ack(区别上面的ACK(1bit)标识,ack是

4bytes)则是上一个包的seq+1,告诉客户端下一个包的seq。

 

3.第三次握手:客户端发回服务端,ACK标识同意接收服务端的连接,此致双向连接都建立好了。这个包的

seq就是上个包的ack,再者这里的ack就是下个包的seq。

socket通信机制:

服务端                            客户端

socket                            socket

bind

listen                              connect

accept(阻塞)

read/write                      write/read

close                            close

那么对于tcp三次握手是在程序的什么时候建立的呢?现在我把客户端bind之后跑到listen之前(未执行

listen),然后从客户端一旦执行connect,立刻被服务端RST了。这里可以说明是由connect来发出tcp

三次握手的第一个SYN包,wireshark可以抓出来。

现在把客户端往下走,调用listen,但是没有调用accept,然后客户端重新调用connect,这时候wireshark就

马上出现了tcp三次握手建立成功。这个时候已经有一个成功建立连接的套接字在TCP/IP协议栈的队列里。

建立连接之后,调用accept函数马上就返回的,accept函数的作用就是从TCP/IP协议栈队列中取出一个成功

建立连接的套接字,用于和用户层交互。accept是阻塞型的,如果accept发现队列里是空的,就会一直阻

塞,直到出现成功连接的套解字。

总计上面的,整个流程是这样的:

服务端                                              客户端

socket                                             socket

bind

listen(端口和IP都已经确定)           connect(发出SYN包)

(<=============tcp连接三次握手=========>)

accept(取出队列中的套解字)

close                                                close

标签:Linux, NetWork, TCP/IP

评论已关闭