TCP通信实现

news2024/11/25 14:35:44

前言

        TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于流的通信协议。它是互联网协议栈(TCP/IP)中的核心协议之一,主要用于保证在计算机网络中可靠地传输数据。

TCP通信的基本特点

  • 面向连接:在发送数据之前,TCP要求通信双方(客户端和服务器)首先建立一个连接,这个过程被称为“三次握手”。连接建立后,数据才可以传输;数据传输完成后,需要释放连接(通过“四次挥手”关闭连接)。

  • 可靠传输:TCP保证数据包的正确传输。通过序列号和确认号的机制,TCP能够检测丢包、乱序、重复等问题,并通过重传机制进行纠正,从而确保数据的完整性和顺序性。

  • 基于流:TCP传输的数据没有消息边界,而是一个连续的数据流。数据可以按照任意大小进行发送和接收,应用层必须根据协议或约定来解析数据边界。

         本小节我们先来实现TCP通信,然后再来细分TCP通信当中的一些细节问题,关于tcp的三次握手和四次挥手看这篇文章:http://t.csdnimg.cn/WWgfZ

一、实现TCP通信 

服务器代码:

//实现TCP服务器文件
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<string.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>
#include<fcntl.h>

int main(int argc, const char *argv[])
{
	
	//1、创建套接字
	int listenfd=socket(AF_INET,SOCK_STREAM,0);
	if(listenfd<0)
	{
		printf("创建失败\n");
		return -1;
	}
	
	//2、绑定套接字
	//填写自己的地址信息,不是必要的
	struct sockaddr_in serveraddr;
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_port=htons(8888);
	serveraddr.sin_addr.s_addr=inet_addr("192.168.124.29");
	int bind_ret=bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
	if(bind_ret<0)
	{
		printf("绑定失败\n");
		return -1;
	}
	//3、建立连接connect
	//监听套接字
	int listen_ret=listen(listenfd,10);
	if(listen_ret<0)
	{
		perror("listen failed:");
		return -1;
	}
	
		//建立连接accept
		int serverfd=accept(listenfd,NULL,NULL);
		if(serverfd<0)
		{
			perror("accept failed:");
			return -1;
		}
	while(1)
	{
		//接收数据
		char buf[100];
		int ret=recv(serverfd,buf,100,0);
		//读取数据发送回去
		buf[ret]='\0';
		int send_ret=send(serverfd,buf,strlen(buf),0);
		if(send_ret<0)
		{
			perror("send failed:");
			return -1;
		}
		if(send_ret==0)
			break;
	}
		

	return 0;
}

然后我们使用网络调试器连接服务器:

 网络调试器下载地址:通过网盘分享的文件:scomm.exe
链接: https://pan.baidu.com/s/1OkiZLT_CeoryEZepaOSGqQ 提取码: 8a85

 如果出现绑定失败如下图:

不用紧张,我们下载号网络调试器之后双击运行;

连接完成之后,在调试器中发送你想要发送的内容,服务器接收到以后,会直接发送到客户端,也就是网络调试器中:

这样我们就完成了一个简单的TCP通信的实现过程 

二、通信原理 (网路传输的封包与拆包)

         数据在通信过程中的传输我们可以这样来看:

数据经过多次的封装,然后再发送给服务器,再每一层的封装过程中,都会加入一个协议,这个协议帮助数据完整的传输(也就是在我们发送数据的时候加入了网络层-IP头(协议)、传输层-TCP头(TCP协议),网络接口层-帧头(MAC地址)这个就是封包过程,接收端做拆包过程)。下面我们就以TCP传输作为例子。

        首先,在客户应用当中我们输入了数据,如上图中的流程图一样,在传输层加入了TCP头,在网络层加入了IP头,在网络接口层加入了MAC帧头,我们仔细来看这些头里面有什么数据。

三、通信过程中的头

         上面我们提到了每层中都有协议,那么具体每个协议里面都有什么内容数据呢,本小节我们就来看看里面有什么数据,这里就要用到一个抓包软件wireshark,像自己抓包的小伙伴可以自己下载,

        首先,我们打开wireshark这个软件

        点击WIAN进入抓包

                当我们实现上面TCP服务器的时候,会出现建立连接的过程

1.MAC帧

        看图中左下角,我们打开第二行是内核空间封装的MAC帧头地址

         里面的信息如下:目标MAC地址(Destination)、源MAC地址(Source),type类型,type后面是十六进制的数,如图中是0X0800则表示只接收本机MAC地址的IPV4类型的数据帧

2. IP头

         点击第三行中的数据,这是我们的IP头信息,在下图中可以看到我们使用的IPV4的版本,如下图左下角部分:

IPv4头部的标准长度为20字节,但它可以通过选项字段增加到60字节。以下是IPv4头的每个字段及其作用:

  1. 版本(Version):4位

    • 该字段指示IP协议的版本。对于IPv4,它的值是4;对于IPv6,它的值是6。这个字段帮助网络设备识别和处理不同版本的IP包。
  2. 首部长度(IHL,Internet Header Length):4位

    • 该字段表示IP头的长度,以32位字为单位。最小值是5(即20字节),如果有选项字段,它的值会更大。此字段用于确定IP头部的结束位置。
  3. 服务类型(Type of Service, ToS):8位

    • 该字段用于指示数据包的优先级和服务质量要求,包括延迟、吞吐量和可靠性等。它现在通常被称为“Differentiated Services Code Point (DSCP)”和“Explicit Congestion Notification (ECN)”字段,用于网络流量的优先级和拥塞通知。
  4. 总长度(Total Length):16位

    • 该字段表示整个IP数据包的长度,包括头部和数据部分,以字节为单位。最大值为65,535字节。这个字段用于接收端计算数据包的总长度并进行正确的解析。
  5. 标识(Identification):16位

    • 该字段用于唯一标识每一个IP数据包,用于分片和重组。当一个大的数据包被分片时,每个片段都有相同的标识,以便接收端能够将这些片段重新组装成完整的数据包。
  6. 标志(Flags):3位

    • 该字段用于控制和标识数据包的分片情况:
      • 第一位(保留,Reserved):应为0,未来可能用于扩展。
      • 第二位(Don't Fragment,DF):如果设置为1,表示数据包不允许分片。
      • 第三位(More Fragments,MF):如果设置为1,表示数据包有更多的分片。
  7. 片偏移(Fragment Offset):13位

    • 该字段表示数据包中片段的偏移量,以8字节为单位。它用于数据包的重组,指示每个片段在原始数据包中的位置。
  8. 生存时间(TTL, Time to Live):8位

    • 该字段用于防止数据包在网络中无限循环。每经过一个路由器或跳数,TTL值减1。当TTL值减到0时,数据包被丢弃,并且通常会发送一个“时间超时”(Time Exceeded)消息回源地址。
  9. 协议(Protocol):8位

    • 该字段指示IP数据包中的数据部分使用的传输层协议,如TCP(值为6)、UDP(值为17)等。它帮助接收方识别数据包的负载协议。
  10. 头部校验和(Header Checksum):16位

    • 该字段用于检查IP头的完整性。它包含IP头部的校验和,接收方使用这个值来检测IP头部是否在传输过程中发生了错误。如果校验和不匹配,数据包会被丢弃。
  11. 源IP地址(Source Address):32位

    • 该字段包含数据包发送方的IP地址,用于在网络中标识数据包的来源。
  12. 目的IP地址(Destination Address):32位

    • 该字段包含数据包接收方的IP地址,用于在网络中标识数据包的目标。
  13. 选项(Options):0-40字节(可选)

    • 这个字段是可选的,可以包含不同的网络控制信息,比如时间戳、安全选项等。如果没有使用选项字段,它的长度为0。选项字段的存在可以影响数据包的处理方式,但大多数应用和协议使用默认的头部设置而不添加选项。
  14. 填充(Padding):0-3字节

    • 这个字段用于确保IP头部长度为32位的倍数。它用于对齐,以确保头部的总长度是4字节的整数倍。

 3.TCP头

       TCP头部是TCP协议中的重要部分,它负责确保数据的可靠传输。TCP头部包含了许多控制信息,用于管理连接、数据流和错误检测。

        同样,我们点击第四行,这里面包含了TCP头部的信息,开始部分是我们的源端口号和目的端口号,在左下角部分

TCP头部格式

TCP头部的标准长度为20字节,但可以通过选项字段扩展。以下是TCP头部的每个字段及其作用:

  1. 源端口(Source Port):16位

    • 该字段表示发送方的端口号。端口号用于在主机上区分不同的应用程序或服务。
  2. 目的端口(Destination Port):16位

    • 该字段表示接收方的端口号,指明数据包应送达的具体应用程序或服务。
  3. 序列号(Sequence Number):32位

    • 该字段用于标识发送的数据字节流中的位置。对于每个数据包,序列号帮助接收方按正确顺序重新组装数据。如果连接是新的,它表示第一个字节的序列号;如果是后续的数据包,它表示数据的字节位置。
  4. 确认号(Acknowledgment Number):32位

    • 该字段用于确认已接收到的数据字节的序列号。确认号表示接收方期望接收的下一个字节的序列号。如果确认号为X,则表示接收方已成功接收序列号小于X的数据。
  5. 数据偏移(Data Offset):4位

    • 该字段表示TCP头部的长度,以32位字为单位。它指示数据部分的起始位置,帮助接收方定位数据部分的开始。
  6. 保留(Reserved):3位

    • 该字段保留供将来使用,当前应设置为0。
  7. 控制位(Flags):9位

    • 该字段包含各种控制标志,用于管理TCP连接的状态:
      • URG(Urgent Pointer):如果设置为1,表示数据包包含紧急数据。
      • ACK(Acknowledgment):如果设置为1,表示确认号字段有效。
      • PSH(Push):如果设置为1,表示接收方应立即将数据传递给应用层,而不是缓冲。
      • RST(Reset):如果设置为1,表示强制重置连接。
      • SYN(Synchronize):如果设置为1,表示请求建立连接,用于三次握手过程。
      • FIN(Finish):如果设置为1,表示数据传输结束,请求关闭连接。
  8. 窗口大小(Window Size):16位

    • 该字段用于流量控制,指示接收方当前的接收窗口大小,表示可以接收的最大字节数。它帮助发送方控制发送速率,以避免接收方缓存溢出。
  9. 校验和(Checksum):16位

    • 该字段用于检查TCP头部和数据部分的完整性。接收方计算和比对校验和,以检测在传输过程中是否发生了错误。如果校验和不匹配,数据包会被丢弃。
  10. 紧急指针(Urgent Pointer):16位

    • 该字段在URG标志位为1时有效,指示紧急数据的结束位置。接收方应优先处理这些紧急数据。
  11. 选项(Options):0-40字节(可选)

    • 该字段用于提供附加的控制信息,如最大报文段长度(MSS)、时间戳、窗口缩放等。选项字段可以扩展TCP的功能,但不是所有的数据包都有选项字段。
  12. 填充(Padding):0-3字节

    • 这个字段用于确保TCP头部长度为32位的倍数。它用于对齐,以确保头部的总长度是4字节的整数倍。
  13. 数据(Data):变长

    • 这是TCP头部之后的数据部分,包括实际传输的应用数据。数据部分的长度由数据偏移字段指示。

TCP头部的应用

  • 连接管理:通过SYN和ACK标志,TCP能够管理连接的建立和关闭。SYN用于建立连接,ACK用于确认数据包的接收。

  • 数据传输:序列号和确认号用于跟踪数据的发送和接收,确保数据包按照正确的顺序到达,并进行重传以纠正丢包。

  • 流量控制:通过窗口大小字段,TCP可以动态调整数据的发送速率,防止接收方缓存溢出。

  • 错误检测:校验和字段用于确保数据的完整性,检测和修复传输中的错误。

  • 紧急数据处理:紧急指针字段用于处理优先级数据,确保紧急数据得到及时处理。

  • 选项扩展:选项字段允许在TCP头部添加附加功能,如优化传输性能和支持更多的网络功能。

4.UDP头         

        UDP(User Datagram Protocol,用户数据报协议)是一个简单的、无连接的传输层协议。与TCP不同,UDP不提供连接管理、流量控制和错误恢复机制,它更注重于提供快速的、低开销的数据传输。UDP头部设计简单且直接,用于快速传输数据。如下图:

         

udp的头很简单

UDP头部格式

UDP头部固定为8字节(64位),每个字段的作用如下:

  1. 源端口(Source Port):16位

    • 该字段表示发送方的端口号。端口号用于在主机上标识不同的应用程序或服务。
  2. 目的端口(Destination Port):16位

    • 该字段表示接收方的端口号,指示数据包应送达的具体应用程序或服务。
  3. 长度(Length):16位

    • 该字段表示UDP头部和数据部分的总长度,以字节为单位。最小值是8字节(仅头部),最大值为65,535字节(包括数据)。这个字段用于接收方计算UDP数据包的总长度,确保完整接收。
  4. 校验和(Checksum):16位

    • 该字段用于检查UDP头部和数据部分的完整性。校验和用于检测在传输过程中是否发生了错误。如果校验和不匹配,数据包可能会被丢弃(具体取决于实现和配置)。校验和字段是可选的,但建议使用,以提高数据传输的可靠性。

        从这里也可以看出UDP通信和TCP通信的区别,我们经常说tcp通信可靠也是因为TCP头中包含数据很多,便于数据传输的完整性,后面我会单独出一篇来介绍 

 总结

  •  MAC帧(以太网帧):以太网帧是数据链路层的一个重要组成部分,用于在局域网(LAN)中传输数据。   
  • IPv4头部:包含用于路由和分片的各种信息,如源和目的IP地址、TTL、协议类型等。
  • TCP头部:提供了连接管理、数据流控制和错误检测的功能,适用于需要可靠数据传输的应用。
  • UDP头部:设计简洁,不提供连接管理和流量控制,适用于需要快速传输的应用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2123610.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面向物联网基础的智能农业环境的节能边缘-雾-云计算架构

这篇论文的标题是《Energy-Efficient Edge-Fog-Cloud Architecture for IoT-Based Smart Agriculture Environment》&#xff0c;作者是Hatem A. Alharbi和Mohammad Aldossary&#xff0c;发表在IEEE Access期刊上。论文的主要内容可以概括为以下几个部分&#xff1a; 摘要&am…

【JVM 工具命令】JAVA程序线上问题诊断,JVM工具命令的使用,jstat, jstack,jmap命令的使用

【JVM 工具命令】JAVA程序线上问题诊断&#xff0c;JVM工具命令的使用&#xff0c;jstat&#xff0c; jstack&#xff0c;jmap命令的使用 1. JVM监控工具&#xff1a; Jstat命令 通过这个命令查询java程序&#xff0c;gc的情况 jstat -gcutil {pid} 5000 12 5000 表示5000…

JavaWeb【day12】--(SpringBootWeb登录认证)

案例-登录认证 在前面的课程中&#xff0c;我们已经实现了部门管理、员工管理的基本功能&#xff0c;但是大家会发现&#xff0c;我们并没有登录&#xff0c;就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的&#xff0c;所以我们今天的主题就是登录认证。 最终我们…

Mysql高级篇(中)—— 索引优化

Mysql高级篇&#xff08;中&#xff09;—— 索引优化 一、索引分析案例案例 1&#xff1a;单表查询案例 2&#xff1a;两表连接查询案例 3&#xff1a;三表连接查询 二、避免索引失效常见索引失效场景简述场景 1场景 2场景 3场景 4场景 5场景 6 三、索引优化文字版示例版 一、…

每日OJ_牛客_数组中出现次数超过一半的数字

目录 牛客_数组中出现次数超过一半的数字 解析代码1 解析代码2 牛客_数组中出现次数超过一半的数字 数组中出现次数超过一半的数字__牛客网 给一个长度为 n 的数组&#xff0c;数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。例如输入一个长度为…

瑞芯微RK3566鸿蒙开发板OpenHarmony标准系统应用兼容性测试指导

本文OpenHarmony标准系统应用兼容性测试指导&#xff0c;适用鸿蒙系统软件开发测试的新手入门学习课程。设备为触觉智能的瑞芯微RK3566开发板&#xff0c;型号Purple Pi OH。是Laval官方社区主荐的一款鸿蒙开发主板。支持Openharmony、安卓Android、Linux的Debian、Ubuntu系统。…

实战项目01-icon图标修改

修改项目图标 引入图片资源&#xff0c;放入指定目录&#xff0c;覆盖掉之前图片即可 目录&#xff1a;entry > src > main > resources > base > media 图片&#xff1a;startIcon.png foreground.png background.png 修改项目标题 需要修改 EntryAbilit…

Deploying Spring Boot Apps Tips

Java PaaS providers chatter command Efficient deployments See also spring-boot-reference.pdf https://docs.spring.io/spring-framework/reference/integration/checkpoint-restore.html

基于JAVA+SpringBoot+Vue的网上商城系统的设计与实现

基于JAVASpringBootVue的网上商城系统的设计与实现 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1…

为数据仓库构建Zero-ETL无缝集成数据分析方案(下篇)

对于从事数据分析的小伙伴们来说&#xff0c;最头疼的莫过于数据处理的阶段。在我们将数据源的原始数据导入数据仓储进行分析之前&#xff0c;我们通常需要进行ETL流程对数据格式进行统一转换&#xff0c;这个流程需要分配专业数据工程师基于业务情况完成&#xff0c;整个过程十…

Java解决Jira单点登录、登出思路介绍

说明&#xff1a; 当前环境的Jira是容器部署的&#xff0c;所以方案中的整个流程是在docker环境下进行分析。且方案为解决思路或者说解决方式的一种&#xff0c;仅供参考&#xff0c;不喜勿喷。当然依然存在个别问题&#xff0c;没能完全优化完&#xff0c;想了解的可以直接看最…

【小中大 / 1】

题目 、 代码 #include <bits/stdc.h> using namespace std; const double eps 1e-8; const int N 1e510; int a[N]; int main() {int n;cin >> n;for(int i 1; i < n; i){cin >> a[i];}sort(a1, an1);int maxx a[n], minn a[1];double midd;if((1…

Mac OS14外接显示器字体过小和放大字体模糊问题的简单解决

文章目录 问题简述解决方法 问题简述 使用Mac mini外接2K 显示器时&#xff0c;默认分辨率是25601440&#xff0c;字体较小&#xff0c;如果切换成19201080&#xff0c;字体又变大模糊。 解决方法 使用HiDP I&#xff08;一种显示技术&#xff0c;使用多个物理像素显示1个像…

一款好用的电子样本册转换器

在数字化时代&#xff0c;电子样本册已成为各行各业必备的工具。一款好用的电子样本册转换器&#xff0c;可以让你在繁杂的资料管理中轻松解脱。今天&#xff0c;就为大家推荐一款实用的电子样本册转换神器&#xff0c;让你的工作效率翻倍&#xff01; 工具推荐&#xff1a;FLB…

做好职业规划,绘制璀璨蓝图!

我们来聊一聊如何做好职业规划&#xff0c;建立自己奋斗的目标和计划。 1、使用 SWOT 模型分析自己的现状 SWOT 分析通过对自己的优势、劣势、机会和威胁加以综合评估&#xff0c;做一个合理的自我分析&#xff0c;帮助我们更清楚地分析自己的现状&#xff0c;发现自身的优势和…

GenAI 客户支持 — 第 3 部分:为人类设计聊天机器人的聊天界面

作者&#xff1a;Ian Moersen 本博客系列揭示了我们的现场工程团队如何使用 Elastic stack 和生成式 AI 开发出一款可爱而高效的客户支持聊天机器人。如果你错过了本系列的其他文章&#xff0c;请务必查看第一部分、第二部分和第四部分。 通过 Web 应用聊天的想法已经存在了很长…

[AHK]ListBox的增删改移等操作示范

ahk v1 中对ListBox的操作&#xff1a;增、删、改、上移、下移等操作。 #singleinstance forcetitle ListBox 例子gui,add,listbox,xm ym w100 r20 vLB choose1 gLBevent,电话|聊天|拍拖|表白|订婚|礼金|礼盒 gui,add,edit ,xm yp250 w200 vEDT -background gui,add,butto…

c++数据结构算法题讲解

那么从本期文章开始&#xff0c;会尽量带大家一起刷题 第一题 题目 关键词 思路 源代码 class MinStack { public: void push(int val) { _st.push(val); if(_minst.empty() || val < _minst.top()) { _minst.push(val); } } void pop() { if(_st.top() _minst.top()) {…

ld_addr + UAF漏洞修复

文章目录 ciscn 2023中一条新的IO链例题&#xff1a;思路&#xff1a;分析&#xff1a;利用&#xff1a; 如何修复UAF漏洞 ciscn 2023中一条新的IO链 如果vtable check不通过&#xff0c;会走_dl_addr&#xff0c;在 _dl_addr中会调用到 在exit_hook中利用的那个函数指针&#…

LCD彩条显示——FPGA学习笔记10

部分素材来自原子哥 一、LCD简介 基本原理&#xff1a;在两块平行玻璃板中填充液晶材料&#xff0c;通过电场控制液晶分子旋转从而达到透光和遮光的目的。 LCD屏幕重要参数&#xff1a;分辨率、像素格式、驱动时序 分辨率&#xff1a; 像素格式&#xff1a; RGB&#xff1a;…