详解TCP和UDP通信协议

目录

OSI的七层模型的主要功能

tcp是什么

TCP三次握手

为什么需要三次握手,两次握手不行吗

TCP四次挥手

挥手会什么需要四次

什么是TCP粘包问题?发生的原因

原因

解决方案

UDP是什么

TCP和UDP的区别

网络层常见协议

利用socket进行tcp传输代码示例

客户端

服务端

利用socket进行udp传输代码示例

客户端

服务端

注意tcp的send/recv和udp的sendto/recvfrom有一点区别

OSI的七层模型的主要功能

  • **物理层:**利用传输介质为数据链路层提供物理连接,实现比特流的透明传输。
  • **数据链路层:**接收来自物理层的位流形式的数据,并封装成帧,传送到上一层
  • **网络层:**将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路径。
  • **传输层:**在源端与目的端之间提供可靠的透明数据传输
  • **会话层:**负责在网络中的两节点之间建立、维持和终止通信
  • **表示层:**处理用户信息的表示问题,数据的编码,压缩和解压缩,数据的加密和解密
  • **应用层:**为用户的应用进程提供网络通信服务

tcp是什么

TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,即位于传输层。

TCP三次握手

三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小 信息。

为什么需要三次握手,两次握手不行吗

TCP四次挥手

建立一个连接需要三次握手,而终止一个连接要经过四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,其实就是TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。
TCP 的连接的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可主动发起挥手动作。

挥手会什么需要四次

什么是TCP粘包问题?发生的原因

一个完整的业务可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,即是无边界的流传输,这个就是TCP的粘包问题。

  • 封包:封包就是在发送数据报的时候为每个TCP数据包加上一个包头,将数据报分为包头和包体两个部分。包头是一个固定长度的结构体,里面包含该数据包的总长度。
  • 拆包:接收方在接收到报文后提取包头中的长度信息进行截取。

原因

1、应用程序写入数据的字节大小大于套接字发送缓冲区的大小.

2、进行MSS大小的TCP分段。( MSS=TCP报文段长度-TCP首部长度)

3、以太网的payload大于MTU进行IP分片。(MTU指:一种通信协议的某一层上面所能通过的最大数据包大小。)

解决方案

1、消息定长。
2、在包尾部增加回车或者空格符等特殊字符进行分割
3、将消息分为消息头和消息尾
4、使用其它复杂的协议,如RTMP协议等。

UDP是什么

是一种提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)的通信协议,即位于传输层。

TCP和UDP的区别

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流:UDP是面向报文的,UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)

4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP首部开销20字节;UDP的首部开销小,只有8个字节

6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

7、UDP是面向报文的,发送方的UDP对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层,论应用层交给UDP多长的报文,它统统发送,一次发送一个。而对接收方,接到后直接去除首部,交给上面的应用层就完成任务了。因此,它需要应用层控制报文的大小

TCP是面向字节流的,它把上面应用层交下来的数据看成无结构的字节流会发送,可以想象成流水形式的,发送方TCP会将数据放入“蓄水池”(缓存区),等到可以发送的时候就发送,不能发送就等着TCP会根据当前网络的拥塞状态来确定每个报文段的大小。

网络层常见协议

利用socket进行tcp传输代码示例

客户端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sock = 0;struct sockaddr_in serv_addr;char buffer[1024] = {0};// 创建 socket 文件描述符if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {std::cout << "Socket creation error" << std::endl;return -1;}serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(PORT);// 将服务端地址转换为二进制if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {std::cout << "Invalid address / Address not supported" << std::endl;return -1;}// 连接到服务器if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {std::cout << "Connection Failed" << std::endl;return -1;}// 发送数据到服务器const char *hello = "Hello from client";send(sock, hello, strlen(hello), 0);std::cout << "Hello message sent" << std::endl;// 读取服务器发送的数据int valread = read(sock, buffer, 1024);std::cout << "Received: " << buffer << std::endl;close(sock);return 0;
}

服务端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int server_fd, new_socket;struct sockaddr_in address;int opt = 1;int addrlen = sizeof(address);char buffer[1024] = {0};// 创建 socket 文件描述符if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 将 socket 绑定到端口 8080if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {perror("setsockopt");close(server_fd);exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");close(server_fd);exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen");close(server_fd);exit(EXIT_FAILURE);}// 接受客户端连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept");close(server_fd);exit(EXIT_FAILURE);}// 读取客户端发送的数据int valread = read(new_socket, buffer, 1024);std::cout << "Received: " << buffer << std::endl;// 发送数据到客户端const char *hello = "Hello from server";send(new_socket, hello, strlen(hello), 0);std::cout << "Hello message sent" << std::endl;close(new_socket);close(server_fd);return 0;
}

利用socket进行udp传输代码示例

客户端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sockfd;char buffer[1024];struct sockaddr_in servaddr;// 创建 socket 文件描述符if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));// 填写服务器信息servaddr.sin_family = AF_INET;servaddr.sin_port = htons(PORT);servaddr.sin_addr.s_addr = INADDR_ANY;// 发送消息到服务器const char *hello = "Hello from client";sendto(sockfd, hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *)&servaddr, sizeof(servaddr));std::cout << "Hello message sent." << std::endl;// 接收服务器消息int n;socklen_t len;n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *)&servaddr, &len);buffer[n] = '\0';std::cout << "Server : " << buffer << std::endl;close(sockfd);return 0;
}

服务端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>#define PORT 8080int main() {int sockfd;char buffer[1024];struct sockaddr_in servaddr, cliaddr;// 创建 socket 文件描述符if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}memset(&servaddr, 0, sizeof(servaddr));memset(&cliaddr, 0, sizeof(cliaddr));// 填写服务器信息servaddr.sin_family = AF_INET; // IPv4servaddr.sin_addr.s_addr = INADDR_ANY;servaddr.sin_port = htons(PORT);// 绑定 socketif (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {perror("bind failed");close(sockfd);exit(EXIT_FAILURE);}int n;socklen_t len;len = sizeof(cliaddr); // 客户端地址长度// 接收客户端消息n = recvfrom(sockfd, (char *)buffer, 1024, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len);buffer[n] = '\0';std::cout << "Client : " << buffer << std::endl;// 发送消息到客户端const char *hello = "Hello from server";sendto(sockfd, hello, strlen(hello), MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len);std::cout << "Hello message sent." << std::endl;close(sockfd);return 0;
}

注意tcp的send/recv和udp的sendto/recvfrom有一点区别

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

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

相关文章

KIVY Button¶

Button — Kivy 2.3.0 documentation Button Jump to API ⇓ Module: kivy.uix.button Added in 1.0.0 The Button is a Label with associated actions that are triggered when the button is pressed (or released after a click/touch). To configure the button, the s…

【论文速读】| 用于安全漏洞防范的人工智能技术

本次分享论文&#xff1a;Artificial Intelligence Techniques for Security Vulnerability Prevention 基本信息 原文作者&#xff1a;Steve Kommrusch 作者单位&#xff1a;Colorado State University, Department of Computer Science, Fort Collins, CO, 80525 USA 关键…

ISO/OSI七层模型

ISO:国际标准化/ OSI:开放系统互联 七层协议必背图 1.注意事项&#xff1a; 1.上三层是为用户服务的&#xff0c;下四层负责实际数据传输。 2.下四层的传输单位&#xff1a; 传输层&#xff1b; 数据段&#xff08;报文&#xff09; 网络层&#xff1a; 数据包&#xff08;报…

Vue项目openlayers中使用jsts处理wkt和geojson的交集-(geojson来源zpi解析)

Vue项目openlayers中使用jsts处理wkt和geojson的交集-(geojson来源zpi解析) 读取压缩包中的shape看上一篇笔记&#xff1a;Vue项目读取zip中的ShapeFile文件&#xff0c;并解析为GeoJson openlayers使用jsts官方示例&#xff1a;https://openlayers.org/en/latest/examples/j…

科技创新引领水利行业升级:深入分析智慧水利解决方案的核心价值,展望其在未来水资源管理中的重要地位与作用

目录 引言 一、智慧水利的概念与内涵 二、智慧水利解决方案的核心价值 1. 精准监测与预警 2. 优化资源配置 3. 智能运维管理 4. 公众参与与决策支持 三、智慧水利在未来水资源管理中的重要地位与作用 1. 推动水利行业转型升级 2. 保障国家水安全 3. 促进生态文明建设…

vb.netcad二开自学笔记5:ActiveX链接CAD的.net写法

一、必不可少的对象引用 使用activex需要在项目属性中勾选以下两个引用&#xff0c;若找不到&#xff0c;则浏览定位直接添加下面两个文件&#xff0c;可以看到位于cad的安装路径下&#xff0c;图中的3个mgd.dll也可以勾选。 C:\Program Files\Autodesk\AutoCAD 2024\Autodes…

实战 | YOLOv8使用TensorRT加速推理教程(步骤 + 代码)

导 读 本文主要介绍如何使用TensorRT加速YOLOv8模型推理的详细步骤与演示。 YOLOv8推理加速的方法有哪些? YOLOv8模型推理加速可以通过多种技术和方法实现,下面是一些主要的策略: 1. 模型结构优化 网络剪枝:移除模型中不重要的神经元或连接,减少模型复杂度。 模型精…

中文大模型基准测评2024上半年报告

中文大模型基准测评2024上半年报告 原创 SuperCLUE CLUE中文语言理解测评基准 2024年07月09日 18:09 浙江 SuperCLUE团队 2024/07 背景 自2023年以来&#xff0c;AI大模型在全球范围内掀起了有史以来规模最大的人工智能浪潮。进入2024年&#xff0c;全球大模型竞争态势日益加…

Obsidian 文档编辑器

Obsidian是一款功能强大的笔记软件 Download - Obsidian

降Compose十八掌之『见龙在田』| Modifier

公众号「稀有猿诉」 原文链接 降Compose十八掌之『见龙在田』| Modifier 通过前面的文章我们学会了如何使用元素来构建和填充我们的UI页面&#xff0c;但这只完成了一半&#xff0c;元素还需要装饰&#xff0c;以及进行动画和事件响应&#xff0c;这才能生成完整的UI。这…

2.5章节python中布尔类型

在Python中&#xff0c;布尔类型&#xff08;Boolean type&#xff09;用于表示真&#xff08;True&#xff09;或假&#xff08;False&#xff09;的值。这是编程中非常基础且重要的一个概念&#xff0c;因为它允许程序进行条件判断&#xff0c;从而根据条件执行不同的代码块。…

智慧校园行政办公-红头文件功能概述

在智慧校园的行政办公系统中&#xff0c;红头文件的管理功能是一项重要的组成部分&#xff0c;它极大地提升了文件处理的效率与规范性。该功能围绕文件的创建、审批、归档等关键环节&#xff0c;进行了全面的数字化改造。 首先&#xff0c;系统内置了多种标准化的红头文件模板&…

一文实践强化学习训练游戏ai--doom枪战游戏实践

一文实践强化学习训练游戏ai–doom枪战游戏实践 上次文章写道下载doom的环境并尝试了简单的操作&#xff0c;这次让我们来进行对象化和训练、验证&#xff0c;如果你有基础&#xff0c;可以直接阅读本文&#xff0c;不然请你先阅读Doom基础知识&#xff0c;其中包含了下载、动作…

打开ps提示dll文件丢失如何解决?教你几种靠谱的方法

在日常使用电脑过程中&#xff0c;由于不当操作&#xff0c;dll文件丢失是一种常见现象。当dll文件丢失时&#xff0c;程序将无法正常运行&#xff0c;比如ps&#xff0c;pr等待软件。此时&#xff0c;我们需要对其进行修复以恢复其功能&#xff0c;下面我们一起来了解一下出现…

【堆 (优先队列) 扫描线】218. 天际线问题

本文涉及知识点 堆 &#xff08;优先队列) 扫描线 LeetCode218. 天际线问题 城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度&#xff0c;请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示&…

景芯SoC训练营DFT debug

景芯训练营VIP学员在实践课上遇到个DFT C1 violation&#xff0c;导致check_design_rule无法通过&#xff0c;具体报错如下&#xff1a; 遇到这个问题第一反映一定是确认时钟&#xff0c;于是小编让学员去排查add_clock是否指定了时钟&#xff0c;指定的时钟位置是否正确。 景芯…

2024年信息系统项目管理师1批次上午客观题参考答案及解析(3)

51、探索各种选项&#xff0c;权衡包括时间与成本、质量与成本、风险与进度、进度与质量等多种因素&#xff0c;在整个过程中&#xff0c;舍弃无效或次优的替代方案&#xff0c;这种不确定性应对方法是()。 A&#xff0e;集合设计 B&#xff0e;坚韧性 C&#xff0e;多种结果…

离线运行Llama3:本地部署终极指南_liama2 本地部署

4月18日&#xff0c;Meta在官方博客官宣了Llama3&#xff0c;标志着人工智能领域迈向了一个重要的飞跃。经过笔者的个人体验&#xff0c;Llama3 8B效果已经超越GPT-3.5&#xff0c;最为重要的是&#xff0c;Llama3是开源的&#xff0c;我们可以自己部署&#xff01; 本文和大家…

大数据------JavaWeb------FilterListenerAJAXAxiosJSON

Filter Filter简介 定义&#xff1a;Filter表示过滤器&#xff0c;是JavaWeb三大组件&#xff08;Servlet、Filter、Listener&#xff09;之一。 作用&#xff1a;它可把对资源&#xff08;Servlet、JSP、Html&#xff09;的请求拦截下来从而实现一些特殊功能 过滤器一般完成…

【QT中实现摄像头播放、以及视频录制】

学习分享 1、效果图2、camerathread.h3、camerathread.cpp4、mainwindow.h5、mainwindow.cpp6、main.cpp 1、效果图 2、camerathread.h #ifndef CAMERATHREAD_H #define CAMERATHREAD_H#include <QObject> #include <QThread> #include <QDebug> #include &…