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

TCP:传输控制协议

1:TCP特点:

(1)面向数据流:
(2)有连接(通信之前必须建立连接)
(3)安全可靠的传输机制
(4)机制复杂,网络资源开销大,
(5)本质只能实现一对一的通信(使用TCP的并发方式可以实现一对多通信)

2:TCP确保安全可靠的机制:

三次握手和四次挥手机制:

三次握手:发生在TCP建立连接时,需要进行三次握手操作,为了确保收发双方在通信之前都已准备数据

SYN:客户端请求和服务端建立连接
ACK:响应报文标志位

三次握手:
在这里插入图片描述

TCP四次挥手:TCP断开连接时,需要进行四次挥手,确保断开连接前双方都已通信结束:先发送FIN的一端数据已经发送完了,为防止另一端还在发送数据(数据还没发送完),另一端发送的ACK和FIN不能同时发送,在另一端完全发送完后再发送FIN

FIN:请求断开连接标志位

ACK:响应报文标志位

在这里插入图片描述

TCP编程流程:

在这里插入图片描述
在这里插入图片描述在这里插入图片描述

三次握手阶段:

在这里插入图片描述

四次挥手阶段:

服务端close()-》客户端send()的过程
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

代码:

#include<stdio.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/types.h>          /* See NOTES */
#include <arpa/inet.h>
#include <unistd.h>
#include<string.h>
int main(void)
{int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd<0){perror("socket error\n");return -1;}struct sockaddr_in seraddr;seraddr.sin_family=AF_INET;seraddr.sin_port=htons(50000);seraddr.sin_addr.s_addr=inet_addr("192.168.0.120");int ret = connect(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));if(ret <0){perror("connect error\n");return -1;}ssize_t cnt =send(sockfd,"hello world",11,0);if(cnt<0){perror("send error\n");return -1;}printf("cnt = %ld\n",cnt);close(sockfd);return 0;
}

服务端函数:

listen函数:

在这里插入图片描述

accept函数:

在这里插入图片描述

recv函数:接收通讯套接字-

在这里插入图片描述
对方断开链接时,将会返回0。

代码

#include<stdio.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <sys/types.h>          /* See NOTES */
#include <arpa/inet.h>
#include <unistd.h>
#include<string.h>int main(int argc, const char *argv[])
{//socket()//bind()//listen()//accept()//recv()//send()//close()int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){perror("socket error");return -1;}struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("192.168.0.179");int ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));if (ret < 0){perror("bind error");return -1;}ret = listen(sockfd, 10);if (ret < 0){perror("listen error");return -1;}int connfd = accept(sockfd, NULL, NULL);if (connfd < 0){perror("accept error");return -1;}char buff[1024] = {0};ssize_t cnt = recv(connfd, buff, sizeof(buff), 0);if (cnt < 0){printf("recv error");return -1;}printf("cnt = %ld, buff = %s\n", cnt, buff);close(connfd);close(sockfd);return 0;
}

TCP粘包问题:

发送方应用层发送的多包数据将来在接收方可能一次读到,产生了粘连。

1:发送方将应用层的两包数据整合为一包发送。

2:接收方不知道一包数据的字节数,多包数据在接收方缓冲区缓存,在接收时将多包数据一起接收了

在这里插入图片描述

解决粘包问题的方法:

1:减慢发送方的发送速度,在每次发送后给它延迟1u秒,usleep(1)。

2:发送方发送指定大小,接收方接收指定大小

指定大小:发送结构体

注意:跨平台间数据传输时要注意结构体对齐问题。

在这里插入图片描述
32位平台和64位平台的结构体大小不同。
在这里插入图片描述
在这里插入图片描述

3:应用层为发送的数据增加分隔符,利用分隔符解析

在这里插入图片描述

4:封装数据帧格式进行发送(提前自定义协议)

在这里插入图片描述

还要封装帧头和帧尾

在这里插入图片描述
AA到BB之间的数据为完整的一帧数据,为防止之间出现帧头或帧尾:
在这里插入图片描述
帧头后封装长度
在这里插入图片描述

帧头

帧尾

有效数据长度:C0

有效数据:

在这里插入图片描述
校验:
在这里插入图片描述

http://www.xdnf.cn/news/18719.html

相关文章:

  • 【前端面试题✨】HTML 篇(一)
  • Java22 stream 新特性 窗口算子:GathererOp 和 GatherSink
  • 机器人控制基础:串级PID控制算法的参数如何整定?
  • 【读论文】Qwen-Image技术报告解读
  • iperf2 vs iperf3:UDP 发包逻辑差异与常见问题
  • 力扣(组合)
  • 人工智能时代下普遍基本收入(UBI)试验的实践与探索——以美国硅谷试点为例
  • LeetCode Hot 100 第二天
  • Java—— 配置文件Properties
  • 【Java SE】抽象类、接口与Object类
  • 秋招面试准备
  • 设计模式详解
  • TypeScript变量声明讲解
  • 个人思考与发展
  • 快速了解命令行界面(CLI)的行编辑模式
  • docker:compose
  • 【PSINS工具箱】MATLAB例程,平面上的组合导航,观测量为位置、速度、航向角,共5维。状态量为经典的15维
  • ModbusTCP与EtherNet/IP协议转换:工控机驱动步进电机完整教程
  • 智慧矿山误报率↓83%!陌讯多模态融合算法在矿用设备监控的落地优化
  • 安装即是已注册,永久可用!
  • Sql server的行转列
  • 数据结构:顺序表
  • C# 项目“交互式展厅管理客户端“针对的是“.NETFramework,Version=v4.8”,但此计算机上没有安装它。
  • 玳瑁的嵌入式日记D24-0823(数据结构)
  • 【基础-判断】使用http模块发起网络请求时,必须要使用on(‘headersReceive’)订阅请求头,请求才会成功。
  • 游戏广告投放数据分析项目:拆解投放的“流量密码”
  • 图像边缘检测
  • qwen2.5vl(2):lora 微调训练及代码讲解
  • Android Studio下载gradle文件很慢的捷径之路
  • 个人禁食伴侣FastTrack