Linux UDP编程流程

news2025/4/8 18:30:09

文章目录

  • UDP编程流程
    • UDP协议无连接的特点
    • UDP协议数据报的特点

UDP编程流程

UDP 提供的是无连接、不可靠的、数据报服务。服务器端和客户端没有什么本质上的区别。编程流程如下:

在这里插入图片描述

socket()用来创建套接字,使用 udp 协议时,选择数据报服务 SOCK_DGRAM。sendto()用来发送数据,由于 UDP 是无连接的,每次发送数据都需要指定对端的地址(IP 和端口)。recvfrom()接收数据,每次都需要传给该方法一个地址结构来存放发送端的地址。recvfrom()可以接收所有客户端发送给当前应用程序的数据,并不是只能接收某一个客户端的数据。

服务器端代码ser.c如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int  main()
{   //1.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        printf("创建失败");
        exit(1);
    }

    struct sockaddr_in saddr,caddr;
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(6000);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");
    
    //2.指定套接字的地址,绑定ip和端口
    int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    if(res==-1)
    {
        printf("绑定失败");
        exit(1);
    }
    int len=sizeof(caddr);
    while(1)
    {
        char buff[128]={0};
    //3.接收客户端的消息,谁发来数据就接收谁的数据,并没有和任何客户端建立连接
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len);
        //客户端的信息(ip和端口)存放到caddr,caddr指定数据的来源,中记录着是谁发的数据
        printf("buff(%d)=%s\n",ntohs(caddr.sin_port),buff);
    //4.向客户端回复数据
        sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr));
    }
}

客户端代码cli.c如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

int main()
{
    //1.创建套接字
    int sockfd=socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd==-1)
    {
        printf("创建失败");
        exit(1);
    }

    struct sockaddr_in saddr;//服务器的地址,ip和端口
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family=AF_INET;
    saddr.sin_port=htons(6000);
    saddr.sin_addr.s_addr=inet_addr("127.0.0.1");

    int len =sizeof(saddr);
    while(1)
    {
        char buff[128]={0};
        printf("输入数据:");
        fgets(buff,128,stdin);

        if(strncmp(buff,"end",3)==0)
        {
            break;
        }

        //2.向服务器端发送数据
        sendto(sockfd,buff,sizeof(buff),0,(struct sockaddr*)&saddr,sizeof(saddr));

        memset(buff,0,sizeof(buff));

        //3.接收服务器端回复的数据
        recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);

        printf("buff=%s\n",buff);
    }

    //4.关闭套接字
    close(sockfd);

}

运行结果:

在这里插入图片描述

从结果可以看出,当服务器端启动之后,可以同时启动多个客户端与客户端通信,但是两个客户端的端口号是不同的。

UDP协议无连接的特点

将服务器端关闭再重启后,客户端依旧可以与服务器端通信,如下图所示:

在这里插入图片描述
这是因为服务器端和客户端是没有建立连接的,当服务器端启动之后,收的到底是哪个客户端的消息我们并不知道,哪个客户端发消息,服务器端就收哪个客户端发来的消息。当服务器端关闭之后是不会像TCP编程那样有底层的协议去进行四次挥手通知客户端它要关闭的,客户端不会收到任何信息并且不知道服务器端是否关闭,所以当我们服务器端关闭之后再重新启动不会影响客户端向服务器端发送数据。同理,客户端关闭也不会给服务器端发送任何信息,客户端的关闭也不会影响服务器端。

如果服务器端关闭后,客户端向服务器端发送数据就会发生阻塞,阻塞在客户端的recvfrom这个地方,因为服务器没启动,端口没有人使用,那么数据就会被丢掉,所以没有服务器端给客户端回复数据,所以就会阻塞在recvfrom这个地方。如下图:

在这里插入图片描述

此时客户端代码cli.c执行完了sendto,接下来执行recvfrom的时候就被阻塞住了,因为没有服务器端给客户端回复消息,此时发送的aaaaaa发给本主机的6000端口,但是本主机的6000端口没有被占用,也就是6000端口没有被使用,所以所发送的数据aaaaaa就直接被丢掉了,所以也不会有服务器端给客户端回复消息,客户端就会在recvfrom这个地方阻塞住。

UDP协议数据报的特点

将服务器端代码ser.c中的recvfrom那一行的代码修改为如下情况,让服务器端一次只收一个字符:

recvfrom(sockfd,buff,1,0,(struct sockaddr*)&caddr,&len);

此时的运行结果:

在这里插入图片描述

出现这样的结果是因为,第一次客户端所发送的"hello",服务器端只收到了一个字符"h",剩下的"ello"被丢掉了,后续的结果也是一样,这是因为UDP协议是数据报服务,不像流式服务一样没有读完会继续读,每次recvfrom就拆一个包,拆一个包要保证把所有的数据都读走,不然剩余的数据就会被丢掉。所以在使用UDP协议的时候必须要保证一次把数据接收完。不用担心两个包合到一起导致收不完数据,因为每次调sendto的时候都要指定对方的地址,这个地址可以一样也可以不一样,所以两个sendto不可能合到一起,因为sendto的目的端可以不一样。不像TCP协议,send一下,再send一下,两次send的内容都会放到同一个缓冲区中,UDP协议是sendto直接打一个包过去,不会出现粘包的现象。数据报服务的特点如下图所示:

在这里插入图片描述

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

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

相关文章

新手小白制作产品册的攻略合集

在如今竞争激烈的市场中&#xff0c;一个精美而专业的产品册可以帮助你吸引更多的客户和提升品牌形象。然而&#xff0c;对于新手小白来说&#xff0c;制作产品册可能会显得有些困难。不用担心&#xff01;小编将告诉大家一些制作产品册的攻略&#xff0c;帮助你轻松入门 首先我…

MySQL学习问题记录

文章目录 MySQL学习问题记录1、查询记录自动根据id排序&#xff1f; MySQL学习问题记录 1、查询记录自动根据id排序&#xff1f; step1&#xff1a;建表 表项信息&#xff1a; 写入数据顺序id为10 2 7 1。查寻时返回记录顺序为1 2 7 10&#xff1f; 更新一条数据后仍然按照…

在Linux系统上用C++将主机名称转换为IPv4、IPv6地址

在Linux系统上用C将主机名称转换为IPv4、IPv6地址 功能 指定一个std::string类型的主机名称&#xff0c;函数解析主机名称为IP地址&#xff0c;含IPv4和IPv6&#xff0c;解析结果以std::vector<std::string>类型返回。解析出错或者解析失败抛出std::string类型的异常消…

第19章_瑞萨MCU零基础入门系列教程之RTC

本教程基于韦东山百问网出的 DShanMCU-RA6M5开发板 进行编写&#xff0c;需要的同学可以在这里获取&#xff1a; https://item.taobao.com/item.htm?id728461040949 配套资料获取&#xff1a;https://renesas-docs.100ask.net 瑞萨MCU零基础入门系列教程汇总&#xff1a; ht…

【基于递归混合尺度:无监督GAN:Pansharpening】

Pansharpening Using Unsupervised Generative Adversarial Networks With Recursive Mixed-Scale Feature Fusion &#xff08;基于递归混合尺度特征融合的无监督生成对抗网络泛锐化&#xff09; 全色锐化(pansharpening)是提高多光谱图像空间分辨率的重要技术。大多数模型都…

记录DatagramSocket的使用 | UDP协议下的数据传输 | java学习笔记

a端 import java.io.*; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress;/*** a端发送“今天星期几”给b端*/ public class UDPa {public static void main(String[] args) throws IOException {//a端绑定9999端口————a端从…

编辑器的缩略图实现原理

一、背景 部分 Web 版的 IDE 编辑器未曾实现缩略图功能&#xff0c;探寻一下缩略图的实现逻辑。以 VSCode 为例。 VSCode 的编辑器是monaco实现的&#xff0c;编辑器的编辑区都是采用的虚拟渲染&#xff0c;即仅渲染可视区的代码&#xff0c;可视区之外的动态去除 DOM 节点。…

Windows上安装和配置Apache Kafka

Apache Kafka是一个开源的流式平台&#xff0c;用于处理实时数据流。它可以用于各种用途&#xff0c;包括日志聚合、事件处理、监控等。本文将向您展示如何在Windows操作系统上安装和配置Apache Kafka。 步骤1&#xff1a;下载和解压Kafka 首先&#xff0c;让我们从Apache Ka…

adworld-web2

web2 GFSJ0627积分 2金币 2 91最佳Writeup由 Robert_Wei 提供 收藏 反馈 难度&#xff1a;2 方向&#xff1a;Web 题解数&#xff1a;108 解出人数&#xff1a;10185 题目来源: CTF 题目描述: 解密 题目场景: http://61.147.171.105:56591 100% 倒计时: 3时59分…

基于SIFT图像特征识别的匹配方法比较与实现

基于SIFT图像特征识别的匹配方法比较与实现 1 匹配器选择 目前常用的匹配器有 BFMatcher and FlannBasedMatcher 1.1 BFMatcher BFMatcher 全称是 Brute-Force Matcher&#xff08;直译即为暴力匹配器&#xff09; 大致原理&#xff1a; 对于 img1 中的每个描述符&#x…

LVS DR模式负载均衡群集部署

目录 1 LVS-DR 模式的特点 1.1 数据包流向分析 1.2 DR 模式的特点 2 DR模式 LVS负载均衡群集部署 2.1 配置负载调度器 2.1.1 配置虚拟 IP 地址 2.1.2 调整 proc 响应参数 2.1.3 配置负载分配策略 2.2 部署共享存储 2.3 配置节点服务器 2.3.1 配置虚拟 IP 地址 2.3.2…

初学unity开发学习笔记----第一天

以下是学习unity知识的心得&#xff0c;类似备忘录&#xff0c;肯定是存在有漏洞的地方或者专业名词使用不恰当的地方。。。 目标&#xff1a;编写小球wasd移动的效果 1.下载unity hub和unity引擎: (1).前往官网:Unity实时内容开发平台 -实时3D引擎、2D、VR&AR可视化数据…

【新版】系统架构设计师 - 软件架构设计<SOA与微服务>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 架构 - 软件架构设计&#xff1c;SOA与微服务&#xff1e; 考点摘要 面向服务SOA&#xff08;★★★★&#xff09;微服务&#xff08;★★★★&#xff09; 基于/面向服务的&#xff08;SOA&#xff09; 在SO…

【新版】系统架构设计师 - 软件架构设计<新版>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 软件架构设计&#xff1c;新版&#xff1e;考点摘要概念架构的 4 1 视图架构描述语言ADL基于架构的软件开发方法ABSDABSD的开发模型ABSDMABSD&#xff08;ABSDM模型&#xff09;的开发过程 软件架…

C++ 多线程(future篇)

引言 在前面介绍了启动线程&#xff0c;以及多线程下如何保证共享资源的竞争访问、线程同步这些。但是thread类无法访问从线程直接返回的值&#xff0c;如果要想获取线程的的执行结果&#xff0c;一般都是依靠全局或static变量&#xff0c;或是以实参传递的变量&#xff0c;然后…

C# 辗转相除法求最大公约数

辗转相除法求最大公约数 public static void CalcGCD(int largeNumber, int smallNumber, out int GCD){GCD 1;int remain -1;while (remain ! 0){remain largeNumber % smallNumber;GCD smallNumber;largeNumber smallNumber;smallNumber remain;}}

华为云云耀云服务器L实例评测|华为云耀云L搭建zerotier服务测试

0. 环境 - Win10 - 云耀云L服务器 1. 安装docker 检查yum源&#xff0c;本EulerOS的源在这里&#xff1a; cd /etc/yum.repos.d 更新源 yum makecache 安装 yum install -y docker-engine 运行测试 docker run hello-world 2. 运行docker镜像 默认配…

计算机专业毕业设计项目推荐03-Wiki系统设计与实现(JavaSpring+Vue+Mysql)

Wiki系统设计与实现&#xff08;JavaSpringVueMysql&#xff09; **介绍****系统总体开发情况-功能模块****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设…

大秒杀系统设计

参考链接&#xff1a;http://www.taodudu.cc/news/show-5770725.html?actiononClick 1. 一些数据 大家还记得2013年的小米秒杀吗&#xff1f;三款小米手机各11万台开卖&#xff0c;走的都是大秒系统&#xff0c;3分钟后成为双十一第一家也是最快破亿的旗舰店。 经过日志统计…

[超硬核] 5000字带走读DuckDB优化器之常量折叠与比较简化

DuckDB优化器之常量折叠与比较简化 本篇文章适合学习C的小伙伴&#xff0c;适合阅读开源项目的小伙伴&#xff0c;更适合学习数据库的小伙伴&#xff0c;欢迎与我一起探索优化器知识。 目录 DuckDB优化器之常量折叠与比较简化1.优化器规则2.表达式重写 2.1 重写/访问算子2.2 应…