162 Linux C++ 通讯架构实战16,UDP/TCP协议的优缺点,使用环境对比。UDP 服务器开发

UDP/TCP协议的优缺点

TCP :面向连接的,可靠数据包传输。对于不稳定的网络层,采取完全弥补的通信方式。丢包重传
    优点:稳定,数据流量稳定,速度稳定,顺序稳定
    
    缺点:传输速度慢,效率低,开销大。
    
    使用场景:数据的完整性要求较高,不追求效率
                        大数据传输,文件传输
    
UDP:无连接的,不可靠的数据包传递,对于不稳定的网络层,采取完全不弥补的通信方式。默认还原网络状况
    优点:速度快,效率高,开销小
    
    缺点:不稳定,数据流量,速度,顺序
    
    使用场景:对时效性要求较高场合,稳定性其次
                        游戏,视频会议,视频电话
一些大的公司:腾讯,华为,阿里---都会在应用层使用数据效验,来弥补UDP的不足

注释

如下是TCP 在第一次连接成功后的网络,使用蓝色标识,那么后面的数据都是会以蓝色的这条路发送,因此保证了数据的顺序。

由于有滑动窗口,保证了数据的顺序,以及数据的流量。

UDP则不同,有可能第一次和后面的每次的通路都不同,发包后就不管了,因此可能会丢包,也是因为每次通路都不同,因此顺序可能会发生变化。

UDP服务器

传输层主要应用的协议模型有两种,一种是TCP协议,另外一种则是UDP协议。TCP协议在网络通信中占主导地位,绝大多数的网络通信借助TCP协议完成数据传输。但UDP也是网络通信中不可或缺的重要通信手段。

相较于TCP而言,UDP通信的形式更像是发短信。不需要在数据传输之前建立、维护连接。只专心获取数据就好。省去了三次握手的过程,通信速度可以大大提高,但与之伴随的通信的稳定性和正确率便得不到保证。因此,我们称UDP为“无连接的不可靠报文传递”。

那么与我们熟知的TCP相比,UDP有哪些优点和不足呢?由于无需创建连接,所以UDP开销较小,数据传输速度快,实时性较强。多用于对实时性要求较高的通信场合,如视频会议、电话会议等。但随之也伴随着数据传输不可靠,传输数据的正确率、传输顺序和流量都得不到控制和保证。所以,通常情况下,使用UDP协议进行数据传输,为保证数据的正确性,我们需要在应用层添加辅助校验协议来弥补UDP的不足,以达到数据可靠传输的目的。

与TCP类似的,UDP也有可能出现缓冲区被填满后,再接收数据时丢包的现象。由于它没有TCP滑动窗口的机制,通常采用如下两种方法解决

  1. 服务器应用层设计流量控制,控制发送数据速度。
  2. 借助setsockopt函数改变接收缓冲区大小。如:

#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);int n = 220x1024setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));

C/S模型-UDP

服务器端流程

socket                

bind

listen                 设置三次握手的客户端的最大个数,UDP无3次握手,因此这一步可有可无

accept               accept是等待客户端的三次连接,UDP无3次握手,这一步不需要

read                   不再适用,因为没有cfd了,换成 recvfrom函数,后面会接受recvfrom函数

小--》大,

write                  不再使用,因为没有cfd了,换成 sendto

客户端流程

socktfd = socket();

connected(socktfd , socket_addr);// connected 函数是TCP做三次连接的,UDP不需要

直接变成了 sendto

recvfrom接受服务器端发送过来的数据

close

recvfrom函数

0表示对端关闭,>0表示读取到的字节数,-1表示失败,errno

       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);
 

对于服务器

sockfd:就是lfd

buf:我要将数据读取后存放哪里

len:我要存放数据的那块内存的大小

flag:0,默认值0表示使用默认的协议

src_addr:表示客户端的信息, 传出参数

addrlen:客户端信息的大小,传出参数

对于客户端

sockfd:就是socket函数后返回的sockfd

buf:我要将数据读取后存放哪里

len:我要存放数据的那块内存的大小

flag:0,默认值0表示使用默认的协议

src_addr:表示服务器端的信息, 传出参数

addrlen:服务器端信息的大小,传出参数

sendto 函数

       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);
成功返回 发送的字节数的大小,-1表示失败,errno

对于服务器

sockfd:就是lfd

buf:我要发送的数据

len:我要发送的数据的大小

flag:0,默认值0表示使用默认的协议

src_addr:表示客户端的信息, 传入参数

addrlen:客户端信息的大小,传入参数

对于客户端

sockfd:就是socket函数后返回的sockfd

buf:我要发送的数据

len:我要发送的数据的大小

flag:0,默认值0表示使用默认的协议

src_addr:表示服务器端的信息, 传入参数

addrlen:服务器端信息的大小,传入参数

由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,保证通讯可靠性的机制需要在应用层实现。

编译运行server,在两个终端里各开一个client与server交互,看看server是否具有并发服务的能力。用Ctrl+C关闭server,然后再运行server,看此时client还能否和server联系上。和前面TCP程序的运行结果相比较,体会无连接的含义。

代码:

SERVER

#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <arpa/inet.h>
#include <ctype.h>#define MAXLINE 80
#define SERV_PORT 6666int main(void)
{struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int sockfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int i, n;sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_port = htons(SERV_PORT);bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));printf("Accepting connections ...\n");while (1) {cliaddr_len = sizeof(cliaddr);n = recvfrom(sockfd, buf, MAXLINE,0, (struct sockaddr *)&cliaddr, &cliaddr_len);if (n == -1)perror("recvfrom error");printf("received from %s at PORT %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));for (i = 0; i < n; i++)buf[i] = toupper(buf[i]);n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));if (n == -1)perror("sendto error");}close(sockfd);return 0;
}

CLIENT

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include <ctype.h>#define MAXLINE 80
#define SERV_PORT 6666int main(int argc, char *argv[])
{struct sockaddr_in servaddr;int sockfd, n;char buf[MAXLINE];sockfd = socket(AF_INET, SOCK_DGRAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);while (fgets(buf, MAXLINE, stdin) != NULL) {n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));if (n == -1)perror("sendto error");n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);if (n == -1)perror("recvfrom error");write(STDOUT_FILENO, buf, n);}close(sockfd);return 0;
}

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

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

相关文章

青藏铁路双寨物流基地扩能改造工程接触网第一杆成功组立

4月2日凌晨&#xff0c;随着吊钩缓缓落下&#xff0c;在中铁电气化局北京电化公司现场作业人员的紧张操作下&#xff0c;青藏铁路双寨物流基地扩能改造工程首根接触网支柱稳稳落在基础上&#xff0c;标志着双寨物流基地扩能改造进入全面施工阶段。 双寨物流基地扩能改造工程包含…

GMSSL学习笔记

概述 GmSSL是由北京大学自主开发的国产商用密码开源库&#xff0c;实现了大部分常用的国密算法&#xff08;SM2、SM3、SM4等&#xff09;以及TLCP协议&#xff0c;使用方法类似openssl。 GmSSL是一个轻量级软件&#xff0c;使用起来也比openssl方便一些。 https://gitee.com…

C#-实现软删除

文章目录 前言1. 使用布尔字段标记删除状态2. 修改查询以忽略软删除的记录3. 实现软删除的方法4. 考虑使用全局查询过滤器5. 处理关联实体6. 考虑性能和存储软删除的好处&#xff1a;软删除的坏处&#xff1a; 总结 前言 后端中&#xff0c;经常使用软删除来标志删除一些数据。…

Part1.Transformer架构

构成&#xff1a; 【手把手教你用Pytorch代码实现Transformer模型&#xff01;从零解读(Pytorch版本&#xff09;-哔哩哔哩】 https://b23.tv/o283hzU

JavaScript逆向爬虫——使用Python模拟执行JavaScript

使用Python模拟执行JavaScript 通过一些调试&#xff0c;我们发现加密参数token是由encrypt方法产生的。如果里面的逻辑相对简单的话&#xff0c;那么我们可以用Python完全重写一遍。但是现实情况往往不是这样的&#xff0c;一般来说&#xff0c;一些加密相关的方法通常会引用…

视觉循迹小车(旭日x3派、opencv)

基于旭日x3派的视觉循迹小车&#xff0c;未完全实现&#xff0c;参考&#xff1a;https://developer.horizon.cc/forumDetail/146176819622746404 效果硬件视觉循迹原理python代码 效果 硬件 1、旭日x3派&#xff08;烧录好系统镜像&#xff09; 2、USB摄像头 3、TB6612 4、小…

C++ //练习 11.29 如果给定的关键字不在容器中,upper_bound、lower_bound和equal_range分别会返回什么?

C Primer&#xff08;第5版&#xff09; 练习 11.29 练习 11.29 如果给定的关键字不在容器中&#xff0c;upper_bound、lower_bound和equal_range分别会返回什么&#xff1f; 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 解释 如果…

HashMap底层源码面试题

面试题1&#xff1a;HashMap是如何实现快速查找的&#xff1f; 答案&#xff1a; HashMap通过哈希表实现快速查找。它内部维护了一个数组&#xff08;称为桶数组或table&#xff09;&#xff0c;每个数组元素是一个链表或红黑树&#xff08;当链表长度超过一定阈值时&#xff…

摄像头校准漫反射板提高识别物体

摄像头校准漫反射板是一种用于摄像头校准的重要工具。在摄像头成像过程中&#xff0c;由于各种因素的影响&#xff0c;如光线、角度、镜头畸变等&#xff0c;会导致摄像头成像出现偏差。为了消除这些偏差&#xff0c;提高摄像头的成像质量&#xff0c;需要使用摄像头校准漫反射…

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍

文章目录 前提嵌入式开发交叉编译GDB调试&#xff0c;QEMU&#xff0c;MAKEFILE练习 目标&#xff1a;通过这一个系列课程的学习&#xff0c;开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提 这个系列的大部分文章和知识来自于&#xff1a;[完结] 循序渐进&#x…

第十四讲:C语言字符函数和字符串函数

目录 1. 字符分类函数 2、字符转换函数 3. strlen的使⽤和模拟实现 4. strcpy 的使⽤和模拟实现 5. strcat 的使⽤和模拟实现 6. strcmp 的使⽤和模拟实现 7. strncpy 函数的使⽤ 8. strncat 函数的使⽤ 9. strncmp函数的使⽤ 10. strstr 的使⽤和模拟实现 11. strt…

[LeetCode][LCR186]文物朝代判断——贪心

题目 LCR 186. 文物朝代判断 展览馆展出来自 13 个朝代的文物&#xff0c;每排展柜展出 5 个文物。某排文物的摆放情况记录于数组 places&#xff0c;其中 places[i] 表示处于第 i 位文物的所属朝代编号。其中&#xff0c;编号为 0 的朝代表示未知朝代。请判断并返回这排文物的…

java开发职业发展和求职建议

在当今竞争激烈的就业市场中&#xff0c;Java开发职业的求职者需要具备一定的技能和知识&#xff0c;以在众多求职者中脱颖而出。以下是一些建议&#xff0c;帮助Java开发者提高自己的竞争力&#xff0c;找到理想的工作。 1. 掌握基本技能&#xff1a;首先&#xff0c;Java开发…

Vue中如何使用Ajax请求是通过第三方库axios或者原生的fetch API来实现的

在Vue中使用Ajax请求通常是通过第三方库&#xff0c;比如axios或者原生的fetch API来实现的。这里我将为你展示如何使用axios库在Vue中进行Ajax请求。 首先&#xff0c;你需要安装axios库。你可以通过npm或者yarn来安装&#xff1a; 使用npm: bash 复制 npm install axi…

mysql的索引类型与数据存储

mysql索引与类型 什么是索引&#xff1f; 索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。我们可以简单理解为&#xff1a;快速查找排好序的一种数据结构。Mysql索引主要有两种结构&#xff1a;BTree索引和Hash索引。我们平常所说的索引&#xff0c;如…

校园圈子小程序,大学校园圈子,三段交付,源码交付,支持二开

介绍 在当今的数字化时代&#xff0c;校园社交媒体和在线论坛成为了学生交流思想、讨论问题以及分享信息的常用平台。特别是微信小程序&#xff0c;因其便捷性、用户基数庞大等特点&#xff0c;已逐渐成为构建校园社区不可或缺的一部分。以下是基于现有资料的校园小程序帖子发…

2024.4.1力扣每日一题——故障键盘

2024.4.1 题目来源我的题解方法一 直接利用StringBuilder的反转函数方法二 字符数组 题目来源 力扣每日一题&#xff1b;题序&#xff1a;2810 我的题解 方法一 直接利用StringBuilder的反转函数 使用StringBuilder构造结果&#xff0c;并利用其反转函数进行翻转 时间复杂度…

opencv如何寻找图片轮廓

在OpenCV中&#xff0c;寻找图片轮廓的基本步骤通常包括以下几个过程&#xff1a; 读取图片&#xff1a;首先&#xff0c;需要读取想要提取轮廓的图片。转换为灰度图&#xff1a;因为轮廓检测通常在灰度图上进行&#xff0c;所以需要将图片转换为灰度图。应用阈值或边缘检测&a…

(已解决)引入本地bootstrap无效,bootstrap和jquery的引入

问题&#xff1a; 首先我是跟着张天宇老师下载的bootstrap文件&#xff0c;新建了一个css文件夹&#xff0c;但是这样子<link rel"stylesheet" type"text/css" src"./css/bootstrap.css">在index.html引入没有用。 解决办法: 1.把建立的…

【opencv】示例-dft.cpp 该程序演示了离散傅立叶变换 (dft) 的使用,获取图像的 dft 并显示其功率谱...

#include "opencv2/core.hpp" // 包含OpenCV核心功能头文件 #include "opencv2/core/utility.hpp" // 包含OpenCV实用程序头文件 #include "opencv2/imgproc.hpp" // 包含OpenCV图像处理头文件 #include "opencv2/imgcodecs.hpp" // 包…