TCP协议三次握手的原因是什么?为什么不用两次握手和4次握手?

今天复习了TCP协议的三次握手,对上一篇C++网络编程有了更深的理解。

当时考研的时候计网学过,这里再总结一下分享。网图都是截图来的,侵删。

TCP协议属于传输层协议,上面的应用层协议包括HTTP、FTP之类,应用层协议是最接近用户的,每往下一层就套一层头部数据来提供给当前层协议解析。那么对于TCP协议,上层传来的数据也会在传输层添加一个TCP头部,当然规则很复杂,我们只需要关注几个重要的就行。

主要关注32位序列号、32位确认号,和几个标志位,例如SYN,ACK,FIN

1.什么是三次握手?三次握手的流程

场景:我是客户端,你是服务器,我们不能像平常讲话一样一起说互相听得到,我不确定你听没听到,你也不确定我听没听到,而且我们所有的话都是要按顺序说的,也就是说每次我要确认你听到我所有的话之后,我才会接着说话。如何确定你收到了?

先看下面这个拟人场景,要是说不会三次握手我是不信的,其实你已经会了,不信看下面。

我:兄弟,你听得到吗,我给你个100, 你听到了给我回个101哈?

你:兄弟兄弟,收到收到,给你发个101,我给你个序列号200哈,你要是收到了给我个201?

我:兄弟,我看到你发的200了,balabala开始唠嗑。

三次握手就是上面的三个步骤。

首先一开始两个机器都是关着的,服务器创建socket并且开始监听模式,详见上一篇博客https://blog.csdn.net/weixin_42324904/article/details/129269208?spm=1001.2014.3001.5501

 // 第1步:创建服务端的socket。
    int listenfd;
    if ( (listenfd = socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); return -1; }
 
    // 第2步:把服务端用于通信的地址和端口绑定到socket上。
    struct sockaddr_in servaddr;    // 服务端地址信息的数据结构。
    memset(&servaddr,0,sizeof(servaddr));
    servaddr.sin_family = AF_INET;  // 协议族,在socket编程中只能是AF_INET。
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);          // 任意ip地址。
    //servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
    servaddr.sin_port = htons(atoi(argv[1]));  // 指定通信端口。
    if (bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)) != 0 )
    { perror("bind"); close(listenfd); return -1; }
    if (listen(listenfd,5) != 0 ) { perror("listen"); close(listenfd); return -1; }

客户端发起连接请求,上一篇博客https://blog.csdn.net/weixin_42324904/article/details/129269208?spm=1001.2014.3001.5501有相关代码,然后就是把上面的拟人小场景翻译过来就可以了,问题不大,还是挺简单的。

往后每次交互的时候双方都有自己的序列号,互相更新,表示数据传到哪里了,有没有传错,例如我现在给你序列号是100,那我希望你给我返回101,这个101的含义是,你100以内接收完了,希望接收到101.

注意:第三次握手可以传送数据了,所以小场景里面有巴拉巴拉,前两次都是不可以的。


两次握手的差别

三次握手如上所示,那么如果说,3次要改成2次的话,怎么改?显然是把中间那一段去掉。

我:兄弟我给你个100,你收到的话给我发个101哈

你:兄弟,我收到了你的100, 我现在给你101, 我给你一个序列号200,你给我发个201。巴拉巴拉

此时链接已经建立了,如果采用2次握手,你已经可以给我发消息了。

想一下图,我懒得画了。

考虑如下情况:

我:兄弟,我给你个100哦,你收到给我发101

。。。 没理我

我:兄弟,你咋不理我,那我给你发个200哦,你收到给我发201。

。。。(网络不太行,前面那个100的在路上没收到,现在刚到)

你:兄弟,我收到了你的100,我现在给你发101,我给你序列号300,你收到给我发301,巴拉巴拉

(这个时候链接建立了,你给我传数据了巴拉巴拉)

我:兄弟,你搞错了,100是我刚才发的,我现在要的是201不是101,你快快stop。

你:兄弟,收到了我stop

(刚才那个200的你现在才收到)

你:兄弟,我收到200了,给你201,我序列300,你给我发301.

开始正常运作。。

注意看上面红色的字,传了一波数据,这波数据是不应该的,所以会造成链接浪费。

三次握手就不会出现这样的情况。

我:兄弟,我给你发100,你给我发101

。。。没理我

我:兄弟,我给你发200,你给我发201

。。。(网络不太行,前面那个100的在路上没收到,现在刚到)

你:兄弟,我收到了你的100,我现在给你发101,我给你序列号300,你收到给我发301,巴拉巴拉

(三次链接这里不会传数据,没有巴拉巴拉,还在等我回复再传数据)

我:兄弟,你搞错了,100是我刚才发的,我现在要的是201不是101,你快快stop。

你:兄弟,收到了我stop

(刚才那个200的你现在才收到)

你:兄弟,我收到200了,给你201,我序列300,你给我发301.

开始正常。

差别就在上面那里。


累了今天不写了,择日在写

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值