TCP通信实现

前言

        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;}//建立连接acceptint 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.mzph.cn/news/879089.shtml

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

相关文章

Android视频编辑:利用FFmpeg实现高级功能

在移动设备上进行视频编辑的需求日益增长&#xff0c;用户期望能够在智能手机或平板电脑上轻松地编辑视频&#xff0c;以满足社交媒体分享或个人存档的需求。Android平台因其广泛的用户基础和开放的生态系统&#xff0c;成为视频编辑应用的理想选择。FFmpeg&#xff0c;作为一个…

Leetcode面试经典150题-55.跳跃游戏

解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {public boolean canJump(int[] nums) {/**如果就一个位置&#xff0c;你本来就在这&#xff0c;肯定可以跳到*/if(nums.length 1) {return true;}/**这个题的解题思路是遍历数组&#xff0c;如果当前位置不在之…

Golang | Leetcode Golang题解之第393题UTF-8编码验证

题目&#xff1a; 题解&#xff1a; const mask1, mask2 1 << 7, 1<<7 | 1<<6func getBytes(num int) int {if num&mask1 0 {return 1}n : 0for mask : mask1; num&mask ! 0; mask >> 1 {nif n > 4 {return -1}}if n > 2 {return n}r…

AI大模型零基础学习到精通:jieba分词用法及原理

2.jieba分词用法及原理 1.概述 上篇文章分析了自然语言处理&#xff0c;特别是中文处理中&#xff0c;分词的几个主要难点。为了解决这些难点&#xff0c;提出了基于字符串匹配的算法和基于统计的分词算法。针对当前的几种分词引擎&#xff0c;对其分词准确度和速度进行了评估…

实时监控视频接入到AS-VJ900拼接系统中,发现服务器的英伟达GPU 驱动状态不对 导致拼接后实时视频请求失败的问题解决

目录 一.问题背景 1.1拼接平台简介 1.2问题描述 二.问题解决过程 2.1查看拼接前视频流 2.2查看GPU驱动 2.3重新安装GPU驱动 2.3.1确认驱动版本 2.3.2卸载不正常驱动 2.3.3重新安装驱动 三.问题解决结果 3.1查看解决结果 3.2nvidia-smi的补充 一.问题背景 1.1拼接…

NLP基础及其代码-tokenizer

基础知识 NLP-分词器&#xff1a;SentencePiece【参考Chinese-LLaMA-Alpaca在通用中文语料上训练的20K中文词表并与原版LLaMA模型的32K词表进行合并的代码】_sentencepiece 中文训练-CSDN博客 【OpenLLM 008】大模型基础组件之分词器-万字长文全面解读LLM中的分词算法与分词器…

TCP通信三次握手、四次挥手

前言 前面我说到了&#xff0c;UDP通信的实现&#xff0c;但我们经常说UDP通信不可靠&#xff0c;是因为他只会接收和发送&#xff0c;并不会去验证对方收到没有&#xff0c;那么我们说TCP通信可靠&#xff0c;就是因为他会进行验证接收端是否能够接收和发送&#xff0c;并且只…

使用Python通过字节串或字节数组加载和保存PDF文档

处理PDF文件的可以直接读取和写入文件系统中的PDF文件&#xff0c;然而&#xff0c;通过字节串&#xff08;byte string&#xff09;或字节数组&#xff08;byte array&#xff09;来加载和保存PDF文档在某些情况下更高效。这种方法不仅可以提高数据处理的灵活性&#xff0c;允…

怎么能实现VIN码充电吗?针对一个单一的VIN码,设置不同的服务费这种计费模式

为了实现VIN码充电并针对单一VIN码设置不同的服务费这种计费模式&#xff0c;需深入了解VIN码充电的实现过程及技术细节。VIN码充电是一种基于车辆识别号码&#xff08;VIN&#xff09;进行充电和计费的方法&#xff0c;适用于新能源汽车的充电桩。具体分析如下&#xff1a; V…

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]interface gigabitethernet 0/0/0 [Huawei-Gigabi…

告别繁琐,IsMyHdOK硬盘测速,即刻享受科技便利

快节奏的生活因科技而精彩纷呈&#xff0c;它赋予我们超越时空的能力&#xff0c;让工作与家庭的天平在忙碌中依然保持平衡——而面对数据爆炸的时代&#xff0c;硬盘作为数据存储与交换的核心部件&#xff0c;其性能直接影响到我们的工作效率和体验。正是在这样的背景下&#…

Python面试常见问题及详细解答:从基础到高级概念全覆盖

创作不易&#xff0c;您的打赏、关注、点赞、收藏和转发是我坚持下去的动力&#xff01; 以下是Python面试中常见的一些问题及其详细答案的整理&#xff1a; 1. Python的可变与不可变对象 问题: 什么是可变对象和不可变对象&#xff1f;举例说明。答案: 可变对象: 可以在原地…

iOS 知识点记录

王巍 博客地址:OneVs Den git地址:onevcat (Wei Wang) GitHub 江湖人称喵神,目前就职于line。喵神的博客涉及方面比较广, 有Obejctive-C, Swift, SwiftUI, Unity等等。博客内容很有深度,非常值得关注。 戴铭 博客地址:戴铭的博客 git地址:ming1016 (戴铭) GitHub 《i…

在Webmin上默认状态无法正常显示 Mariadb V11.02及以上版本

OS: Armbian OS 24.5.0 Bookworm Mariadb V11.02及以上版本 Webmin&#xff1a;V2.202 非常小众的问题&#xff0c;主要是记录一下。 如题 Webmin 默认无法 Mariadb V11.02及以上版本 如果对 /etc/webmin/mysql/config 文件作相应调整就可以再现Mariadb管理界面。 路径文件&am…

Mamba模型学习笔记

笔记来源&#xff1a;bilibili Transformer 的死穴 Transformer 结构的核心是自注意力机制层&#xff0c;无论是 encoder 还是 decoder&#xff0c;序列数据都先经过位置编码后喂给这个模块。 但是自注意力机制的计算范围仅限于窗口内&#xff0c;而无法直接处理窗口外的元素…

java spring定时任务-动态任务

cron表达式 在线生成https://cron.qqe2.com/ 6个时间刻度的话 * * * * * * 分别对应 秒 分 时 日 月 星期 &#xff1b; 7个时间刻度的话 * * * * * * * 分别对应 秒 分 时 日 月 星期 年&#xff1b;每隔5秒执行一次&#xff1a;*/5 * * * * ? 每隔1分钟执行一次&#xff1a…

kubectl的安装使用

1. Windows下载kubectl 2.将kucectl的所在目录添加到PATH环境变量下 3.运行 kubectl version --client 命令来测试kubectl是否正确安装并显示其版本信息。这个命令会显示kubectl客户端的版本信息&#xff0c;如果一切正常&#xff0c;这将确认kubectl已经成功安装在你的Windo…

基于SSM的汽车租赁系统+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

鸿蒙HarmonyOS应用开发者高级认证重点知识详解

✍️作者简介&#xff1a;小北编程&#xff08;专注于HarmonyOS、Android、Java、Web、TCP/IP等技术方向&#xff09; &#x1f433;博客主页&#xff1a; 开源中国、稀土掘金、51cto博客、博客园、知乎、简书、慕课网、CSDN &#x1f514;如果文章对您有一定的帮助请&#x1f…

骑砍模型修改逻辑

这篇博客用作日志的性质。 一&#xff0c;在自定义战场中测试自己制作好的地图 1、将制作好的地图保存到Mount & Blade II Bannerlord\Modules\SandBoxCore\SceneObj内 2、用Notepad打开 \Mount & Blade II Bannerlord\Modules\CustomBattle\ModuleData\custom_battl…