`
xitong
  • 浏览: 6198412 次
文章分类
社区版块
存档分类
最新评论

自己动手学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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics