UDP编程

news2024/11/24 1:46:50

前置知识

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

sockfd:表示要发送数据的套接字描述符。它是由socket函数创建的套接字返回的文件描述符。

buf:是一个指向要发送数据的缓冲区的指针。数据将从这个缓冲区复制到套接字发送。

len:表示要发送的数据的长度,以字节为单位。

flags:是一个可选的参数,用于控制发送操作的行为。它可以取以下标志之一或它们的组合:

0:没有特殊的标志,表示普通的发送操作。
MSG_DONTROUTE:指示数据包不应该被路由。
MSG_OOB:用于发送TCP数据(带外数据)。
MSG_NOSIGNAL:在发送数据时忽略SIGPIPE信号,如果连接已断开,则返回错误而不是导致进程终止。

该函数返回发送的字节数,如果出现错误,返回值为-1。以下是函数返回值的一些可能情况:

= 0:表示发送成功,并返回发送的字节数。

-1:表示发送过程中发生错误。可以通过检查全局变量errno来确定具体错误的类型。常见的错误包括:

EINTR:操作被信号中断。
EAGAIN 或 EWOULDBLOCK:套接字已设置为非阻塞模式,并且发送操作将阻塞。
EBADF:无效的文件描述符。
EFAULT:buf指针指向无效的内存地址。
ENOTCONN:套接字未连接。

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

       ssize_t recv(int sockfd, void *buf, size_t len, int flags);

sockfd:表示要接收数据的套接字描述符。它是由socket函数创建的套接字返回的文件描述符。

buf:是一个指向接收数据的缓冲区的指针。接收到的数据将被复制到这个缓冲区。

len:表示接收数据的最大长度,以字节为单位。如果接收到的数据长度超过len,则超出部分的数据将被截断。

flags:是一个可选的参数,用于控制接收操作的行为。它可以取以下标志之一或它们的组合:
0:没有特殊的标志,表示普通的接收操作。 MSG_DONTWAIT 或 MSG_NONBLOCK:以非阻塞模式接收数据。
MSG_OOB:接收带外数据。 MSG_PEEK:接收数据但不从接收队列中删除数据。

该函数返回接收到的字节数,如果出现错误,返回值为-1。以下是函数返回值的一些可能情况:
= 0:表示接收成功,并返回接收到的字节数。
0:表示连接已关闭,没有更多数据可接收。

-1:表示接收过程中发生错误。可以通过检查全局变量errno来确定具体错误的类型。常见的错误包括:
EINTR:操作被信号中断。 EAGAIN 或 EWOULDBLOCK:套接字已设置为非阻塞模式,并且没有可用的数据。
EBADF:无效的文件描述符。 EFAULT:buf指针指向无效的内存地址。

       #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);

sockfd:表示要发送数据的套接字描述符。它是由socket函数创建的套接字返回的文件描述符。

buf:是一个指向要发送数据的缓冲区的指针。数据将从这个缓冲区复制到套接字发送。

len:表示要发送的数据的长度,以字节为单位。

flags:是一个可选的参数,用于控制发送操作的行为。它可以取以下标志之一或它们的组合:
0:没有特殊的标志,表示普通的发送操作。 MSG_DONTROUTE:指示数据包不应该被路由。
MSG_OOB:用于发送紧急数据(带外数据)。
MSG_NOSIGNAL:在发送数据时忽略SIGPIPE信号,如果连接已断开,则返回错误而不是导致进程终止。

dest_addr:是一个指向目标地址结构的指针,其中包含要发送到的目标地址信息。该结构可以是sockaddr、sockaddr_in或sockaddr_in6,具体取决于套接字的地址类型。

addrlen:表示目标地址结构的长度,以字节为单位。对于IPv4地址,通常为sizeof(struct
sockaddr_in);对于IPv6地址,通常为sizeof(struct sockaddr_in6)。

该函数返回发送的字节数,如果出现错误,返回值为-1。以下是函数返回值的一些可能情况:

= 0:表示发送成功,并返回发送的字节数。

-1:表示发送过程中发生错误。可以通过检查全局变量errno来确定具体错误的类型。常见的错误包括:

EINTR:操作被信号中断。 EAGAIN 或 EWOULDBLOCK:套接字已设置为非阻塞模式,并且发送操作将阻塞。
EBADF:无效的文件描述符。
EFAULT:buf或dest_addr指针指向无效的内存地址。 ENOTCONN:套接字未连接。

       #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:表示要接收数据的套接字描述符。它是由socket函数创建的套接字返回的文件描述符。

buf:是一个指向接收数据的缓冲区的指针。接收到的数据将被复制到这个缓冲区。

len:表示接收数据的最大长度,以字节为单位。如果接收到的数据长度超过len,则超出部分的数据将被截断。

flags:是一个可选的参数,用于控制接收操作的行为。它可以取以下标志之一或它们的组合:
0:没有特殊的标志,表示普通的接收操作。 MSG_DONTWAIT 或 MSG_NONBLOCK:以非阻塞模式接收数据。
MSG_OOB:接收带外数据。
MSG_PEEK:接收数据但不从接收队列中删除数据。

src_addr:是一个指向发送者地址结构的指针,用于存储发送者的地址信息。在函数调用之前,需要将该结构初始化为目标地址结构的类型,例如sockaddr_in或sockaddr_in6。

addrlen:是一个指向存储发送者地址结构长度的变量的指针。在函数调用之前,需要将该变量初始化为src_addr指向的结构的大小。

该函数返回接收到的字节数,如果出现错误,返回值为-1。以下是函数返回值的一些可能情况:

= 0:表示接收成功,并返回接收到的字节数。

0:表示连接已关闭,没有更多数据可接收。

-1:表示接收过程中发生错误。可以通过检查全局变量errno来确定具体错误的类型。常见的错误包括:

EINTR:操作被信号中断。
EAGAIN 或 EWOULDBLOCK:套接字已设置为非阻塞模式,并且没有可用的数据。
EBADF:无效的文件描述符。
EFAULT:buf或src_addr指针指向无效的内存地址

UDP流程示意图

在这里插入图片描述

UDP(User Datagram Protocol,用户数据报协议)是一种网络传输协议,位于传输层,提供面向无连接的数据报传输服务。与TCP(Transmission Control Protocol,传输控制协议)相比,UDP更为简单、轻量级,但不提供可靠的数据传输和流控制机制

无连接性:UDP是一种无连接的协议,发送端和接收端在通信之前不需要建立连接。每个UDP数据报都是独立的单元,可以独立发送、接收和处理,没有固定的数据传输顺序。

不可靠性:UDP不提供可靠的数据传输机制。它不保证数据报的完整性、顺序性或可靠性。发送的数据报可能会丢失、重复、乱序或损坏。应用程序需要自行处理这些问题。

高效性:由于UDP没有建立连接和维护状态的开销,以及较小的首部开销,UDP具有较低的通信延迟和网络负载。它适用于实时应用程序或对传输延迟要求较低的场景。

支持广播和多播:UDP支持广播(向局域网内的所有主机发送数据)和多播(向特定组内的主机发送数据)功能,可以在局域网中有效地分发数据。

适用场景:UDP适用于一些特定的应用场景,如实时音视频传输(如语音通话、视频会议)、网络广播、域名解析(DNS)等。在这些场景下,速度和实时性比可靠性更重要。

服务器端代码

没有使用线程和进程,但是可以实现并发处理。

int udpserver()
{
    printf("%s %d\n", __func__, __LINE__);
    struct sockaddr_in addr_in;
    int fd = -1;
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        printf("%s %d fd<0\n", __func__, __LINE__);
        return 0;
    }

    int b_reuse = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof(int));

    //  2、绑定
    memset(&addr_in, 0, sizeof(addr_in));  // 将变量addr_in置0
    addr_in.sin_port = htons(SERVER_PORT); // 将端口号从本地字节序转换为网络字节序
    addr_in.sin_family = AF_INET;
    addr_in.sin_addr.s_addr = htonl(INADDR_ANY); // 任意IP可以运行
    int rec = bind(fd, (struct sockaddr *)&addr_in, sizeof(addr_in));
    if (rec < 0)
    {
        printf("%s %d rec<0\n", __func__, __LINE__);
        return 0;
    }

    struct sockaddr_in clientin;
    bzero(&clientin, sizeof(clientin));
    char buf[256];
    bzero(buf, sizeof(buf));
    socklen_t addr_len = sizeof(clientin);
    int reclen = -1;
    printf("%s %d bind ok \n", __func__, __LINE__);
    while (1)
    {
        printf("%s %d 111111111111 \n", __func__, __LINE__);
        bzero(buf, sizeof(buf));
        reclen = 0;
        reclen = recvfrom(fd, buf, 256 - 1, 0, (struct sockaddr *)&clientin, &addr_len);
        printf("%s %d reclen  = %d\n", __func__, __LINE__, reclen);
        if (reclen < 0)
        {
            printf("%s %d reclen < 0\n", __func__, __LINE__);
            continue;
        }
        else
        {
            printf("%s %d 11111reclen  = %d\n", __func__, __LINE__, reclen);
        }

        printf("%s %d buf = %s\n", __func__, __LINE__, buf);
        char ipv4_arr[16];

        if (!inet_ntop(AF_INET, (void *)&clientin.sin_addr, ipv4_arr, sizeof(clientin)))
        {
            printf("%s %d err \n", __func__, __LINE__);
        }
        printf("Recived from(%s :%d),data:%s", ipv4_arr, ntohs(clientin.sin_port), buf);
        if (!strncasecmp(buf, "exit", strlen("exit")))
        {
            printf("Recived from(%s :%d) exit", ipv4_arr, ntohs(clientin.sin_port));
            return 0;
        }
    }
    close(fd);
    return 0;
}

客户端代码

执行方法:

/*
.client server_ip server_port
*/

void usage(char *s)
{
    printf("%s %d %s serv_ip ser_port\n", __func__, __LINE__, s);
    printf("%s %d  serv_ip : server ip address\n", __func__, __LINE__);
    printf("%s %d  ser_port: server port (>5000)\n", __func__, __LINE__);
}

/*
.client server_ip server_port
*/
int udpclient(int argc, char *argv[])
{
    printf("%s %d\n", __func__, __LINE__);

    if (argc < 3)
    {
        usage(argv[0]);
    }
    int fd = -1;
    int port = 4004;
    // 1、创建套接字 UDP
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //注意这个地方!!!
    {
        printf("%s %d socket < 0\n", __func__, __LINE__);
        return 0;
    }
    port = atoi(argv[2]);

    struct sockaddr_in clientin;
    bzero(&clientin, sizeof(clientin));
    clientin.sin_family = AF_INET;   // 设置地址属性
    clientin.sin_port = htons(port); // 设置端口号
    int rec = inet_pton(AF_INET, argv[1], (void *)&clientin.sin_addr.s_addr);
    if (rec != 1)
    {
        printf("%s %d rec!= 1\n", __func__, __LINE__);
        return 0;
    }
    char buf[1024];
    while (1)
    {
        fprintf(stderr,"pls input string:");
        memset(buf, 0, 1024);
        char *rec_p = fgets(buf, 1024 - 1, stdin);
        if (rec_p == NULL)
        {
            printf("%s %d rec_p == NULL\n", __func__, __LINE__);
            continue;
        }
        sendto(fd, buf, strlen(buf), 0, (struct sockaddr *)&clientin, sizeof(clientin));
        int recstr = strncasecmp(buf, "exit", strlen("exit"));
        if (0 == recstr)
        {
            printf("%s %d q======\n", __func__, __LINE__);
            break;
        }
    }
close(fd);
    return 0;
}

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

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

相关文章

高级SQL语句

高级SQL语句 建立实验环境高级语句1.---- SELECT ----显示表格中一个或数个字段的所有数据记录2.---- DISTINCT ----不显示重复的数据记录3.---- WHERE ----有条件查询4.---- AND OR ----且 或 &#xff08;一般配合where使用&#xff09;5.---- IN ----显示已知的值的数据记录…

【人工智能技术专题】「入门到精通系列教程」零基础带你掌握人工智能全流程技术体系和实战指南(人工智能理论知识概论)

零基础带你掌握人工智能全流程技术体系和实战指南 前言专栏介绍专栏说明学习大纲前提条件面向读者学习目标人工智能背景介绍概念说明定义 目标方向目标人工智能的主要目标人工智能的应用领域 人工智能学科领域人工智能分类基于应用的人工智能弱AI&#xff08;弱人工智能&#x…

【干货】Android系统定制基础篇:第二部分(Launcher3支持键盘切换焦点、开发者模式密码确认、禁止非预装应用安装、配置时间)

1、Android Launcher3支持键盘切换焦点 Android Launcher3 默认并不支持键盘操作&#xff0c;无法切换焦点&#xff0c;在一些需要支持键盘或遥控操作的设备中无法使用&#xff0c;因些对 Launcher3 做简单修改&#xff0c;使其支持键盘切换焦点。 diff --git a/packages/app…

在字节跳动做了5年软件测试,无情被辞,想给划水的兄弟提个醒

先简单交代一下背景吧&#xff0c;某不知名 985 的本硕&#xff0c;17 年毕业加入字节&#xff0c;以“人员优化”的名义无情被裁员&#xff0c;之后跳槽到了有赞&#xff0c;一直从事软件测试的工作。之前没有实习经历&#xff0c;算是5年的工作经验吧。 这5年之间完成了一次…

JS-快速入门

目录 变量原生数据类型模板字符串字符串的内置属性、方法数组数组创建方式数组值操作获取值添加值删除值判断是否是数组获取值的索引 对象创建对象&#xff0c;为对象创建新属性对象值存到同名常(变)量中 对象数组和JSON创建对象数组对象数组取值对象数组转JSON数据 if条件语句…

ELK技术堆栈(yum安装部署)

ELK技术堆栈&#xff08;yum安装部署&#xff09; 目录 ELK技术堆栈可以应用于各种场景 ELK的工作原理如下&#xff1a; 它由三个核心组件组成&#xff1a; 部署步骤&#xff1a;&#xff08;单台部署&#xff09; 环境部署&#xff1a; 安装JAVA环境&#xff1a;&#…

数据库系统概述——第十章 数据库恢复技术(知识点复习+练习题)

&#x1f31f;博主&#xff1a;命运之光 &#x1f984;专栏&#xff1a;离散数学考前复习&#xff08;知识点题&#xff09; &#x1f353;专栏&#xff1a;概率论期末速成&#xff08;一套卷&#xff09; &#x1f433;专栏&#xff1a;数字电路考前复习 &#x1f99a;专栏&am…

单页面应用是什么?优缺点?如何弥补缺点

文章目录 导文单页面应用是什么&#xff1f;优点&#xff1a;缺点&#xff1a;弥补缺点的方法&#xff1a; 导文 Web单页应用就是指只有一个Web页面作为入口的应用 在浏览器中运行期间不会重新加载页面。也就是说浏览器一开始会加载它必需的thml、css和js 之后所有的交互操作都…

Godot 4 源码分析 - 命令行参数

粗看Godot 4的源码&#xff0c;稍微调试一下&#xff0c;发现一大堆的命令行参数。在widechar_main中 Error err Main::setup(argv_utf8[0], argc - 1, &argv_utf8[1]); Main::setup中&#xff0c;各命令行参数加入到List<Stirng> args中&#xff0c;并通过OS::get…

技术引领 踏浪而行 2023 A+CLUB 北京峰会 | 活动回顾

6月10日&#xff0c;“技术引领 踏浪而行”2023 ACLUB 北京峰会活动圆满举办&#xff0c;近70家机构超百人参会&#xff0c;其中北京及周边地区优秀私募占比八成。私募、券商、专家学者、业内先进解决方案&#xff08;包括算力、存储、网络、软件&#xff09;供应商从不同角度分…

【2023unity游戏制作-mango的冒险】-7.玩法实现

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

0805曲面及其方程-向量代数与空间解析几何

文章目录 1 曲面研究的基本问题2 旋转曲面3 柱面4 二次曲面4.1 定义4.2 研究方法4.3 九种二次曲面 结语 1 曲面研究的基本问题 曲面研究的两个基本问题&#xff1a; 已知一曲面作为点的几何轨迹时&#xff0c;建立这曲面的方程&#xff1b;已知x,y和z直接的一个方程时&#x…

如何在 Ubuntu 上实现 Nuxeo 与 ONLYOFFICE 文档集成

1. 概览 我们持续提供一系列易于使用的教程&#xff0c;向大家介绍如何将开源办公套件 ONLYOFFICE 文档集成到第三方 Web 服务中。ONLYOFFICE 文档根据 AGPLv.3 许可分发&#xff0c;包含处理文本文档、电子表格和演示文稿的编辑器&#xff0c;提供全套编辑及格式设置工具&…

Linux之进程间通信之管道

进程间通信的目的: 1、数据传输&#xff1a;一个进程需要将它的数据发售那个给另外一个进程。 2、资源共享&#xff1a;多个进程之间需要共享同样的资源。 3、通知事件&#xff1a;一个进程需要向另外一个或者一组进程发送消息&#xff0c;通知它们发生了某种事件(比如&…

java中避免使用“isSuccess“作为变量名的原因和解决方法

阿里巴巴Java开发手册的说法 在阿里巴巴Java开发手册中关于这一点&#xff0c;有过一个『强制性』规定&#xff1a; 其他原因 另外根据Java命名约定&#xff0c;方法名应该以动词开头&#xff0c;而变量名应该以名词或形容词开头。使用"isSuccess"作为变量名可能…

AAAI 2023 | 语言模型如何增强视觉模型的零样本能力 ?

文章链接&#xff1a;https://arxiv.org/abs/2207.01328 项目地址&#xff1a;https://github.com/zjukg/DUET 该论文设计了一种新的零样本学习范式&#xff0c;通过迁移语言模型中的先验语义知识&#xff0c;与视觉模型的特征感知能力进行对齐&#xff0c;以增强后者对于未见过…

nacos集成springcloud实现配置中心功能

1. 在nacos控制台创建namespace 2. 创建SpringCloud项目 大家注意springboot和springcloud的版本对应&#xff0c;可以去官网查看。 https://spring.io/projects/spring-cloud#learn <properties><java.version>11</java.version><poi.version>5.2.…

VSCode使用CodeWhisperer(AI编程)

安装AWS Toolkit插件&#xff0c;点击侧边插件搜索并安装 2.点击aws ->CodeWhisperer ->Start 3.在下拉菜单中点击Use a personal email to sign up and sign in with AWS Builder ID 4.点Copy Code and Proceed&#xff0c;这会自动复制一些东西 5. 收到提示打开外部网…

高德API JS 地图获取多个坐标点的中心点

高德API JS 地图获取多个坐标点的中心点 一、需求 我需要&#xff1a; 在地图上展示多个地点地图缩放到合适的大小&#xff0c;要求刚好能显示全部点位边缘留有一部分间隔。 做成如图所示这样。 二、需要用到的 AMap 类库 经过一下午的研究&#xff0c;弄出来了。 需要以…

【计算机网络自顶向下】简答题习题总结(一)

计算机网络是什么 两个及以上具有独立操作系统的计算机通过某些介质连接成的相互共享软硬件资源的集合体。 计算机网络两大功能 连通性和共享 如何描述Internet 分为两方面 具体构成 计算机互连设备、通信链路、分组交换设备 提供服务&#xff1a; 提供网络应用基础架构为分布式…