今天复习了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.
开始正常。
差别就在上面那里。
累了今天不写了,择日在写