当前位置: 首页 > news >正文

TCP高频知识点

本篇文章主要讲述一下在面试过程中TCP的高频知识点

1.TCP三次握手流程图:

  1. 客户端发送一个SYN(同步)报文段给服务器,选择一个初始序列号,并设置SYN标志位为1。
  2. 服务器接收到客户端的SYN报文段后,回复一个ACK(确认)报文段,其中确认号设置为客户端发送的序列号加1,同时也选择一个初始序列号,并设置SYN和ACK标志位为1。
  3. 客户端接收到服务器的ACK报文段后,回复一个ACK报文段作为确认应答。其中确认号设置为服务器发送的序列号加1。

2.TCP的基本性质 

1.TCP是全双工的 可靠的 基于字节流的传输协议

2.同一个五元组只允许建立一条连接

3.通过序列号可以实现数据包按序收发 丢失重传

3.TCP三次握手的作用

  1. 确认双方的通信能力:通过三次握手,可以确保客户端和服务器都正常工作并且能够互相通信。
  2. 同步双方的初始序列号:TCP连接需要使用序列号来分割数据流,并提供可靠性保证。通过握手过程中的交换序列号,双方可以确定初始的序列号值。
  3. 防止旧连接影响新连接:在网络中可能存在延迟、重复或失序等问题,通过三次握手可以避免由于旧连接还未完全关闭而导致新连接产生混淆

TCP为什么不能进行两次挥手

1.无法避免旧的重复的初始化  从而造成资源的浪费

2.无法同步双端其实序列号 从而无法保证可靠传输

TCP四次挥手:

  1. 客户端发送一个终止连接请求给服务器,即发送一个FIN(Finish)报文段。
  2. 服务器接收到FIN报文段后,回复一个确认应答ACK报文段,表示已经接收到关闭请求。
  3. 服务器通知上层应用程序关闭连接,并发送一个FIN报文段给客户端。
  4. 客户端接收到服务器的FIN报文段后,回复一个确认应答ACK报文段,表示已经接收到服务器的关闭请求。
  5. 等待一段时间,确保双方都收到了对方的确认应答ACK报文段,然后彻底关闭连接。

TCP四次挥手的意义:

首先,TCP是一个全双工的协议,意味着客户端和服务器可以同时发送和接收数据。因此,在关闭连接时需要进行一系列步骤来确保双方都能够知道对方的关闭意图,并处理未及时接收的数据。

其次,四次挥手中包含两个方向上各两个报文段(FIN和ACK),用于通知对方自己准备关闭连接。这样可以保证每一方都有机会发出确认,避免一方过早地关闭连接导致数据丢失或重传。

还有一个重要的原因是,客户端在发送最后一个ACK报文段之后进入了"时间等待"状态。这是为了等待一定时间,以确保网络中所有延迟传输的数据都被接收完毕。如果立即关闭连接而不等待,可能会导致服务端发送的最后一部分数据无法被客户端正常接收。

TCP三次握手代码实例:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {// 创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 服务器地址和端口struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8888);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");// 发起连接请求connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));char buffer[1024];// 发送SYN报文段(第一次握手)send(sockfd, "SYN", strlen("SYN"), 0);// 接收服务端返回的SYN+ACK报文段(第二次握手)memset(buffer, 0, sizeof(buffer));recv(sockfd, buffer, sizeof(buffer)-1, 0);std::cout << "Received: " << buffer << std::endl;if (strcmp(buffer, "SYN+ACK") == 0) {// 发送ACK报文段(第三次握手)send(sockfd, "ACK", strlen("ACK"), 0);std::cout << "Handshake completed." << std::endl;} else {std::cout << "Handshake failed." << std::endl;close(sockfd);return -1;}// 关闭连接close(sockfd);return 0;
}

在这个示例代码中,首先创建一个套接字(socket)(注意socket使用),然后设置服务器地址和端口。使用connect函数发起连接请求。接下来,发送SYN报文段表示客户端希望建立连接。通过recv函数接收服务端返回的SYN+ACK报文段,并进行判断。如果接收到正确的报文段,则向服务端发送ACK报文段确认连接建立成功。最后,关闭连接。

TCP四次挥手代码实例:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>int main() {// 创建套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);// 服务器地址和端口struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8888);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");// 发起连接请求connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));char buffer[1024];// 发送FIN报文段(第一次挥手)send(sockfd, "FIN", strlen("FIN"), 0);// 接收服务端返回的ACK报文段(第二次挥手)memset(buffer, 0, sizeof(buffer));recv(sockfd, buffer, sizeof(buffer)-1, 0);std::cout << "Received: " << buffer << std::endl;if (strcmp(buffer, "ACK") == 0) {// 接收服务端发送的FIN报文段(第三次挥手)memset(buffer, 0, sizeof(buffer));recv(sockfd, buffer, sizeof(buffer)-1, 0);std::cout << "Received: " << buffer << std::endl;if (strcmp(buffer,"FIN") == 0) {// 发送ACK报文段(第四次挥手)send(sockfd,"ACK",strlen("ACK"), 0);std::cout << "Connection closed." << std::endl;}} else {std::cout << "Handshake failed." << std::endl;close(sockfd);return -1;}// 关闭连接close(sockfd);return 0;
}

在这个示例代码中,首先创建一个套接字(socket),然后设置服务器地址和端口。使用connect函数发起连接请求。接下来,发送FIN报文段表示客户端希望关闭连接。通过recv函数接收服务端返回的ACK报文段,并进行判断。如果接收到正确的ACK报文段,则继续接收服务端发送的FIN报文段。最后,向服务端发送ACK报文段确认关闭连接

好了 本篇文章就到这里结束了 在这里 小编给大家推荐一个课程:

https://xxetb.xetslk.com/s/2PjJ3T

相关文章:

  • 物联网中基于WIFI的室内温度检测系统设计
  • 【React】如何使antd禁用状态的表单输入组件响应点击事件?
  • C++三剑客之std::optional(一) : 使用详解
  • 常见范数介绍
  • css浮动
  • C/C++模板初阶
  • 如何写好一个简历
  • Github 2024-02-12 开源项目日报 Top10
  • 【数据结构】链表OJ面试题5《链表的深度拷贝》(题库+解析)
  • 【春节特辑】金融IT运维新视角:回望2023年变革浪潮,前瞻2024年创新风潮
  • (三十五)大数据实战——Superset可视化平台搭建
  • Java运算符和表达式
  • 网络协议与攻击模拟_16HTTP协议
  • 【OpenHarmony硬件操作】led灯和key的操作
  • Mac中管理多版本Jdk
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Android组件 - 收藏集 - 掘金
  • Apache的80端口被占用以及访问时报错403
  • Hibernate最全面试题
  • IOS评论框不贴底(ios12新bug)
  • Java 网络编程(2):UDP 的使用
  • Java基本数据类型之Number
  • JSDuck 与 AngularJS 融合技巧
  • js写一个简单的选项卡
  • Python学习笔记 字符串拼接
  • React-redux的原理以及使用
  • spring + angular 实现导出excel
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 从零搭建Koa2 Server
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 给github项目添加CI badge
  • 关于springcloud Gateway中的限流
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 基于web的全景—— Pannellum小试
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 力扣(LeetCode)22
  • 如何合理的规划jvm性能调优
  • 使用 Docker 部署 Spring Boot项目
  • 小程序上传图片到七牛云(支持多张上传,预览,删除)
  • 云大使推广中的常见热门问题
  • ​批处理文件中的errorlevel用法
  • #define,static,const,三种常量的区别
  • #Linux杂记--将Python3的源码编译为.so文件方法与Linux环境下的交叉编译方法
  • (20050108)又读《平凡的世界》
  • (C语言)二分查找 超详细
  • (SpringBoot)第二章:Spring创建和使用
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (三)mysql_MYSQL(三)
  • (四)鸿鹄云架构一服务注册中心
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库