UDP通信机制详解

news2025/1/18 7:19:53

在这里插入图片描述

欢迎关注博主 Mindtechnist 或加入【Linux C/C++/Python社区】一起学习和分享Linux、C、C++、Python、Matlab,机器人运动控制、多机器人协作,智能优化算法,滤波估计、多传感器信息融合,机器学习,人工智能等相关领域的知识和技术。


UDP通信机制详解

    • 1. UDP通信流程
    • 2. UDP客户端与服务端实现
    • 3. 心跳包
    • 4. TCP/UDP应用场景


专栏:《Linux从小白到大神》《网络编程》


1. UDP通信流程

前面介绍了TCP,TCP是面向连接的、安全的、流式传输协议。UDP是面向无连接的、不安全的、报式传输协议。UDP通信流程如下:

  • 服务器端:

    • 创建套接字 - socket

      • 第二个参数使用SOCK_DGRAM,表示报式协议,即UDP。TCP使用的是SOCK_STREAM。
    • 绑定IP和端口:bind

      • fd
      • struct sockaddr —— 服务器
    • 通信

      • 接收数据:recvfrom

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

        同accept的第2、3个参数使用方法相同。

        • sockfd:文件描述符
        • buf:接收数据缓冲区
        • len:buf的最大容量
        • flags:0
        • src_addr:另一端的IP和端口, 传出参数
        • addrlen:传入传出参数
      • 发送数据: sendto

        ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
        
        • sockfd:socket函数创建出来的
        • buf:存储发送的数据
        • len:发送的数据的长度,注意是发送数据的大小,而不是buf的大小 strlen()。
        • flags:0
        • dest_addr:另一端的IP和端口
        • addrlen:dest_addr长度
    • UDP服务器端:需要一个套接字, 通信

  • 客户端:

    • 创建一个用于通信的套接字:socket

    • 通信

      • 发送数据:sendto,如果发送的数据太大,sendto会调用失败,UDP报文的长度是有上限的。

        • 需要先准备好一个结构体:struct sockaddr_in

          • 存储服务器的IP和端口
      • 接收数据:recvform

  • udp的数据是不安全的, 容易丢包

    • 丢包, 丢全部还一部分?

      • 只能丢全部,不存在只丢一部分的情况
    • 优点: 效率高

UDP通信流程示意图如下

在这里插入图片描述

2. UDP客户端与服务端实现

server

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, const char* argv[])
{
    // 创建套接字
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd == -1)
    {
        perror("socket error");
        exit(1);
    }
    
    // fd绑定本地的IP和端口
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(8765);
    serv.sin_addr.s_addr = htonl(INADDR_ANY);
    int ret = bind(fd, (struct sockaddr*)&serv, sizeof(serv));
    if(ret == -1)
    {
        perror("bind error");
        exit(1);
    }

    struct sockaddr_in client;
    socklen_t cli_len = sizeof(client);
    // 通信
    char buf[1024] = {0};
    while(1)
    {
        int recvlen = recvfrom(fd, buf, sizeof(buf), 0, 
                               (struct sockaddr*)&client, &cli_len);
        if(recvlen == -1)
        {
            perror("recvform error");
            exit(1);
        }
        
        printf("recv buf: %s\n", buf);
        char ip[64] = {0};
        printf("New Client IP: %s, Port: %d\n",
        inet_ntop(AF_INET, &client.sin_addr.s_addr, ip, sizeof(ip)),
        ntohs(client.sin_port));

        // 给客户端发送数据
        sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&client, sizeof(client));
    }
    
    close(fd);

    return 0;
}

client

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, const char* argv[])
{
    // create socket
    int fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd == -1)
    {
        perror("socket error");
        exit(1);
    }

    // 初始化服务器的IP和端口
    struct sockaddr_in serv;
    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_port = htons(8765);
    inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);
    //把点分十进制字符串 "127.0.0.1" 转成整形,并存到&serv.sin_addr.s_addr中

    // 通信
    while(1)
    {
        char buf[1024] = {0};
        fgets(buf, sizeof(buf), stdin);
        // 数据的发送 - server - IP port
        sendto(fd, buf, strlen(buf)+1, 0, (struct sockaddr*)&serv, sizeof(serv));

        // 等待服务器发送数据过来
        recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL); 
        //服务器的IP和port已经在在初始化的时候知道了,传NULL即可
        printf("recv buf: %s\n", buf);
    }
    
    close(fd);

    return 0;
}

3. 心跳包

UDP是无连接的通信协议,那么如何去判断客户端和服务端是否处于连接状态呢?这就是心跳机制:

  • 心跳机制

    • 不会携带大量的数据
    • 每隔一定时间 服务器 → 客户端 / 客户端→服务器 发送一个数据包
  • 心跳包看成一个协议

    • 应用层协议
  • 判断网络是否断开

    • 有多个连续的心跳包没收到或没有回复
    • 关闭通信的套接字
  • 重连

    • 重新初始套接字
    • 继续发送心跳包
  • 乒乓包

    • 比心跳包携带的数据多一些
    • 除了知道连接是否存在,还能获取一些信息

如何理解心跳包呢——比如说,坐火车过隧道的时候,微信会提示服务器已断开连接,通过隧道后,微信会自己连上服务器。微信是如何知道和服务器断开连接了呢?就是通过心跳包机制。

比如,提前约定好,每隔多少秒客服端向服务器发1,如果服务器收到1,则回复客户端2,客户端收到2再发1,如此循环。如果客户端发送完1没有收到服务器回复的2,那么客户端将会再次发送1,测试几次如果依然没有回复,那么客户端会提示“服务器已断开连接”。

在这里插入图片描述

心跳包只能判断有没有连接,而乒乓包可以携带一些数据。

乒乓包——比如微信,如果有人给你发消息,或者有人发布朋友圈,给你点赞,都会有一个小红点提示,那么你的手机微信是怎么知道有人给你点赞,有人发朋友圈的呢?就是通过乒乓包不停的去询问。但是乒乓包也不是能携带所有数据,我们看到小红点,得点进去,然后手机客户端向服务器请求数据才能看到具体发了啥内容,评论了啥内容。心跳包只能判断是否连接,乒乓包可以携带少量提示信息。

4. TCP/UDP应用场景

  • TCP使用场景

    • 对数据安全性要求高的时候

      • 登录数据的传输 —— 比如用户名密码
      • 文件传输
    • HTTP协议

      • 传输层协议 —— TCP
  • UDP使用场景

    • 效率高 —— 实时性要求比较高

      • 视频聊天、直播
      • 通话
    • 有实力的大公司

      • 使用UDP
      • 在应用层自定义协议来做数据校验,既保证了传输效率,又保证了不丢数据。

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


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

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

相关文章

Helm常用命令记录

问: 到哪里去搜索helm package? 答: artifacthub.io helm versionhelm repo add bitnami https://charts.bitnami.com/bitnamihelm install my-release bitnmai/mysqlkubectl get po --all-namespaceshelm uninstall my-release 安装monitoring,推荐kube-prometheus-stack&am…

【SWAT水文模型】SWAT水文模型建立及应用第三期:基于世界土壤数据库HWSD建立土壤库

SWAT水文模型建立及应用&#xff1a;土壤库建立 1 简介2 土壤数据下载2.1 数据下载方式2.1.1 世界土壤数据库HWSD数据2.1.2 中国土壤数据库 2.2 数据下载 3 土壤数据的准备3.1 SWAT土壤数据库参数3.2 提取HWSD中土壤参数3.3 土壤类型分布图的处理3.4 土壤质地转化3.5 土壤参数的…

人工智能浪潮中,AI如何为企业降本增效?

人工智能浪潮下&#xff0c;企业应如何抓住机遇&#xff0c;用AI降本增效&#xff1f;如何选择适合自身产业的人工智能服务&#xff1f;如果你想了解更多&#xff0c;本文或许能给你提供一点思路。 一、企业如何利用AI降本增效 在人工智能浪潮下&#xff0c;已有多款AI产品问世…

京东APP百亿级商品与车关系数据检索实践 | 京东云技术团队

导读 本文主要讲解了京东百亿级商品车型适配数据存储结构设计以及怎样实现适配接口的高性能查询。通过京东百亿级数据缓存架构设计实践案例&#xff0c;简单剖析了jimdb的位图(bitmap)函数和lua脚本应用在高性能场景。希望通过本文&#xff0c;读者可以对缓存的内部结构知识有…

一文带你写好:项目说明文档README.md

1、前言 公开项目中&#xff0c;一个好的 README 能帮助我们的公开项目&#xff0c;在 GitHub 上的众多项目和开发人员中脱颖而出&#xff1b;商业项目中&#xff0c;一个好的 README 能帮助部门同事更好理解用途和项目进展。下面我们一起讨论什么是 README 自述文件以及如何编…

如何使用node发布自己的包

一、新建文件夹 gzmTestNode二、npm init {"name": "gzmTestNode","version": "1.0.0","description": "处理不同日期函数组件","main": "index.js","scripts": {"test&quo…

从爆火的“哇呀挖”,思考我软件开发的人生意义何在?

【 在什么样的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种什么样的种子&#xff0c;开什么样的花&#xff0c;在小小的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种小小的种子&#xff0c;开小小的花&#xff0c;在大大的花园里面&#xff0c;挖呀挖呀挖&#xff0c;种大大…

springboot+vue火车订票管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的火车订票管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

String [中]

目录 一、 string 的深浅拷贝 0x00 构造函数与析构函数的实现 0x01 拷贝构造 0x02 赋值 0x03 整体代码 二、 string的实现 0x01 引入 0x02 c_str 0x03 默认构造函数 三、size()与operator[]的实现 0x01 size()的实现 0x02 operator[]的实现 0x03 遍历实现 四、迭代器…

同步任务、异步任务、宏任务、微任务、任务的执行过程实例详解、setTimeout()是同步还是异步

一、前言 JavaScript是单线程语言&#xff0c;也就是说&#xff0c;只有一条通道&#xff0c;且js中任务是按顺序依次执行的&#xff0c;但若有一个任务时间过长&#xff0c;就会让后续任务一直等待。为了解决这个问题&#xff0c;将任务分为同步任务和异步任务&#xff0c;异…

文案把卖点被埋没?如此挖掘电商产品卖点,让你轻松获客

绝大部分电商卖家开店面临的最大问题就是不知道如何写文案&#xff0c;直接复制品牌的文案容易被告Q权&#xff0c;自己写的又不吸引人&#xff0c;复制竞争对手的更是无法脱颖而出。同时你也不知道这个文案到底好不好&#xff0c;在别人那里可行的文案&#xff0c;可能你就完全…

CTF-PHP反序列化漏洞3-构造POP链

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;在于他所拥有的。可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防。我的…

宽表 VS 多表关联,谁才是大数据分析的最佳选择?

各位数据的朋友&#xff0c;大家好&#xff0c;我是老周道数据&#xff0c;和你一起&#xff0c;用常人思维数据分析&#xff0c;通过数据讲故事。 前段时间和一个客户就数据中台搭建的一些问题进行了交流&#xff0c;其中讨论最多的是到底是用宽表来实现业务需求&#xff0c;…

Lecture 13(Preparation):Network Compression

目录 Network Pruning Knowledge Distillation Parameter Quantization Architecture Design Dynamic Computation 下面介绍五个network compression的技术。这五个技术都是以软体为导向的&#xff0c;在软体上面对network进行压缩&#xff0c;不考虑硬体加速部分。 Netwo…

springboot+vue校园宿舍管理系统

项目简介 分享一个SpringBootvue所做的一个项目&#xff0c;有需要的私信 1.项目描述 访问地址 http://localhost:8088/login.html?redirect_urlhttp://localhost:8087/myproject 超级管理员账户 账户名&#xff1a;admin 密码&#xff1a;123456 系统管理员账户 账户名…

【系统集成项目管理工程师】计算题专题一

一、决策树和期望货币值 1、项目经理向客户推荐了四种供应商选择方案。每个方案损益值已标在下面的决策树上。根据预期收益值&#xff0c;应选择设备供应商 A.供应商1B.供应商2C.供应商3D.供应商4 解题&#xff1a; 供应商 1&#xff1a;60% * 10000 &#xff08;-30000&am…

DDR基础

欢迎关注我的博客网站nr-linux.com&#xff0c;图片清晰度和&#xff0c;排版会更好些&#xff0c;文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…

Hadoop 3:YARN

YARN简介 Apache Hadoop YARN &#xff08;Yet Another Resource Negotiator&#xff0c;另一种资源协调者&#xff09;是一种新的Hadoop资源管理器。 YARN是一个【通用资源管理系统和调度平台】&#xff0c;可为上层应用提供统一的资源管理和调度。 它的引入为集群在利用率、…

数据结构学习记录——堆的小习题(对由同样的n个整数构成的二叉搜索树(查找树)和最小堆,下面哪个说法是不正确的)

目录 习题一 习题二 习题三 答案区 解析区 习题一 习题二 习题三 习题一 一、下列序列中哪个是最小堆&#xff1f; .2&#xff0c;55&#xff0c;52&#xff0c;72&#xff0c;28&#xff0c;98&#xff0c;71 .2&#xff0c;28&#xff0c;71&#xff0c;72&#x…

排序(数据结构系列13)

目录 前言&#xff1a; 排序算法的引言&#xff1a; 1.插入排序 1.1直接插入排序 1.2希尔排序 2.选择排序 2.1直接选择排序 2.2堆排序 3.交换排序 3.1冒泡排序 3.2快速排序 3.2.1Hoare版 3.2.2挖坑法 3.2.3前后指针法 4.归并排序 5.排序总结 结束语: 前言&…