网络编程代码实例:用户数据报协议(UDP)简单版

news2024/11/25 10:34:08

文章目录

  • 前言
  • 代码仓库
  • 内容
  • 代码(有详细注释)
    • server.c
    • client.c
    • Makefile
  • 结果
  • 总结
  • 参考资料
  • 作者的话

前言

网络编程代码实例:用户数据报协议(UDP)简单版。


代码仓库

  • yezhening/Environment-and-network-programming-examples: 环境和网络编程实例 (github.com)
  • Environment-and-network-programming-examples: 环境和网络编程实例 (gitee.com)

内容

  • 使用用户数据报协议(UDP)

  • 一个服务端连接一个客户端

  • 一次自动通信


代码(有详细注释)

server.c

// 头文件————————————————————
// #include <sys/socket.h> // socket()、sockaddr、bind()、recvfrom()、sendto()
#include <stdio.h>  //(perror())、printf()
#include <stdlib.h> //exit()
// #include <netinet/in.h> //sockaddr_in、(htons())
#include <string.h>    //bzero()、strncpy()
#include <arpa/inet.h> //inet_pton()
// #include <unistd.h>     //close()

// 全局常量————————————————————
const g_serv_port = 3333; // 服务端的端口号
const g_buff_size = 16;   // 消息缓冲区的大小

// 主函数————————————————————
int main(int arg, char *argv[])
{
    // 网络连接————————————————————
    int sock_fd; // 套接字文件描述符
    // 创建套接字并获取套接字文件描述符
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
        perror("socket() error");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in serv_addr; // 服务端网络信息结构体
    // 初始化服务端网络信息结构体
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(g_serv_port);
    if ((inet_pton(AF_INET, "0.0.0.0", &serv_addr.sin_addr)) != 1)
    {
        perror("inet_pton() error");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字与网络信息
    if ((bind(sock_fd, (struct sockaddr *)(&serv_addr), sizeof(serv_addr))) == -1)
    {
        if ((close(sock_fd)) == -1)
        {
            perror("bind() close() error");
            exit(EXIT_FAILURE);
        }

        perror("bind() error");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in clie_addr; // 客户端网络信息结构体
    socklen_t clie_addr_size;     // 客户端网络信息结构体大小
    bzero(&clie_addr, sizeof(clie_addr));
    clie_addr_size = sizeof(struct sockaddr);

    // 传输数据————————————————————
    char msg_recv[g_buff_size]; // 从客户端接收的消息缓冲区
    char msg_send[g_buff_size]; // 发送到客户端的消息缓冲区
    bzero(&msg_recv, sizeof(*msg_recv));
    bzero(&msg_send, sizeof(*msg_send));

    if ((recvfrom(sock_fd, msg_recv, g_buff_size, 0, (struct sockaddr *)(&clie_addr), &clie_addr_size)) == -1) // 接收数据
    {
        if ((close(sock_fd)) == -1)
        {
            perror("recvfrom() close() error");
            exit(EXIT_FAILURE);
        }

        perror("recvfrom() error");
        exit(EXIT_FAILURE);
    }
    printf("Received message: %s\n", msg_recv); // 接收的消息

    strncpy(msg_send, msg_recv, g_buff_size);                                                               // 发送的消息
    if ((sendto(sock_fd, msg_send, g_buff_size, 0, (struct sockaddr *)(&clie_addr), clie_addr_size)) == -1) // 发送数据
    {
        if ((close(sock_fd)) == -1)
        {
            perror("sendto() close() connect_fd error");
            exit(EXIT_FAILURE);
        }

        perror("sendto() error");
        exit(EXIT_FAILURE);
    }

    // 关闭套接字文件描述符
    if ((close(sock_fd)) == -1)
    {
        perror("close() error");
        exit(EXIT_FAILURE);
    }

    return 0;
}

client.c

// 头文件————————————————————
// #include <sys/socket.h> //socket()、sockaddr、sendto()、recvfrom()
#include <stdio.h>  //(perror())、printf()
#include <stdlib.h> //exit()
// #include <netinet/in.h> //sockaddr_in、(htons())
#include <string.h>    //bzero()、strncpy()
#include <arpa/inet.h> //inet_pton()
// #include <unistd.h>     //close()

// 全局常量————————————————————
const g_serv_port = 3333; // 服务端端口号
const g_buff_size = 16;   // 消息缓冲区大小

// 主函数————————————————————
int main(int argc, char *argv[])
{
    // 网络连接————————————————————
    int sock_fd; // 套接字文件描述符
    // 创建套接字并获取套接字文件描述符
    if ((sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
        perror("socket() error");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in serv_addr; // 服务端网络信息结构体
    // 初始化服务端网络信息结构体
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(g_serv_port);
    if ((inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr)) != 1)
    {
        perror("inet_pton() error");
        exit(EXIT_FAILURE);
    }

    // 数据传输
    char msg_send[g_buff_size]; // 发送到服务端的消息缓冲区
    char msg_recv[g_buff_size]; // 从服务端接收的消息缓冲区
    bzero(&msg_recv, sizeof(*msg_recv));
    bzero(&msg_send, sizeof(*msg_send));

    strncpy(msg_send, "Hello", 6);                                                                             // 发送的消息
    if ((sendto(sock_fd, msg_send, g_buff_size, 0, (struct sockaddr *)(&serv_addr), sizeof(serv_addr))) == -1) // 发送数据
    {
        if ((close(sock_fd)) == -1)
        {
            perror("sendto() close() error");
            exit(EXIT_FAILURE);
        }

        perror("sendto() error");
        exit(EXIT_FAILURE);
    }

    if ((recvfrom(sock_fd, msg_recv, g_buff_size, 0, NULL, NULL)) == -1) // 接收数据
    {
        if ((close(sock_fd)) == -1)
        {
            perror("recvfrom() close() error");
            exit(EXIT_FAILURE);
        }

        perror("recvfrom() error");
        exit(EXIT_FAILURE);
    }
    printf("Received message: %s\n", msg_recv); // 接收的消息

    // 关闭套接字文件描述符
    if ((close(sock_fd)) == -1)
    {
        perror("close() error");
        exit(EXIT_FAILURE);
    }

    return 0;
}

Makefile

#变量
targets = server client

#伪目标
.PHONY : all
all : $(targets) 

#规则
server : server.c
	gcc -o server server.c 

client : client.c
	gcc -o client client.c

#伪目标
.PHONY : clean
clean :
	rm $(targets)

结果

server:

在这里插入图片描述

client:

在这里插入图片描述


总结

网络编程代码实例:用户数据报协议(UDP)简单版。


参考资料

  • 《UNIX环境高级编程(第3版)》作者:W.Richard Stevens,Stephen A.Rago
  • 《UNIX网络编程(第3版)》作者:W.Richard Stevens,Bill Fenner,Andrew M.Rudoff

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

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

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

相关文章

[ICLR 2020] Reducing Transformer Depth on Demand with Structured Dropout

Contents IntroductionTraining Transformers with Random Structured PruningRandomly Dropping Structures at Training TimePruning at Inference Time ExperimentsReferences Introduction 作者提出了一种新的 structural pruning 方法 LayerDrop&#xff0c;通过在训练时…

FastDFS集群搭建

简介 FastDFS是什么&#xff1f;我们这里可以看一下度娘的解释。FastDFS是一个开源的轻量级分布式文件系统&#xff0c;它对文件进行管理&#xff0c;功能包括&#xff1a;文件存储、文件同步、文件访问&#xff08;文件上传、文件下载&#xff09;等&#xff0c;解决了大容量…

Python base64模块加密解密

一、为何使用base64加密解密 为了安全机制的系统&#xff0c;在用户登录的时候&#xff0c;会采用一系列措施保护用户信息&#xff0c;防止程序被攻击&#xff0c;比如&#xff1a;将用户输入的密码加密处理&#xff0c;在控制台看请求接口看到的密码是加密过的密码&#xff0c…

前端 Chrome 插件推荐

1.Ajax Interceptor 场景&#xff1a; 1.前端本地在开发&#xff0c;后端接口还没好&#xff0c;可以提前mock数据&#xff0c;并且真实的模拟网络请求。可以对代码不侵入的方式&#xff0c;提高编码效率。后面真实联调速度就会快很多。 2.当你参与项目的一部分开发的时候&a…

WPF实现PasswordBox切换明密功能

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

生产mysql遇到kill不掉的sql的解决方法

一、问题描述 今天上线&#xff0c;生产mysql有个2700万数据的大表lt_integral_detail_info&#xff0c;准备给这个表加字段、加索引&#xff1b; 执行加字段加索引的命令比较费时&#xff0c;结果这时有人对这个表执行了多个select count(*)操作&#xff0c;导致直接把Navic…

SQL优化(5):limit优化

在数据量比较大时&#xff0c;如果进行limit分页查询&#xff0c;在查询时&#xff0c;越往后&#xff0c;分页查询效率越低。 我们一起来看看执行limit分页查询耗时对比&#xff1a; 找一个有1000W数据量的表进行测试分析 查询前10条数据分页&#xff0c;耗时0.03秒 查询100…

【力扣】二叉树的分层遍历1和2

二叉树的分层遍历1 链接&#xff1a;二叉树的分层遍历1&#xff1a; 首先&#xff0c;我们需要知道什么是二叉树的层序遍历。二叉树的层序遍历是一种按照树的层次从上到下&#xff0c;从左到右访问每个节点的方法。例如&#xff0c;对于下面这棵二叉树&#xff1a; 1/ \2 3…

Linux_红帽8学习笔记分享_7(Crontab计划任务+NTP时间同步服务器)

Linux_红帽8学习笔记分享_7(Crontab计划任务NTP时间同步服务器) 文章目录 Linux_红帽8学习笔记分享_7(Crontab计划任务NTP时间同步服务器)1. 系统时间1.1查看系统时间1.2设置系统时间 2.周期性计划任务2.1认识周期性任务服务2.2寻找定时文件的配置文件2.3用户定时任务的格式2.4…

行业方案|智能网联汽车数据安全治理框架

近年来&#xff0c;信息技术的快速发展&#xff0c;加快了汽车产业的变革。与此同时&#xff0c;随着智能化、网联化的推进&#xff0c;汽车的数据安全问题也日益凸显。当下&#xff0c;如何保障数据安全&#xff0c;成为影响智能汽车产业健康发展的关键问题。 4月18日&#x…

Linux Ansible创建任务并执行

目录 通过add-hoc执行anbise任务 通过Playbook剧本方式执行任务 Playbook包含的常用对象 Yaml语法 对Yaml格式自动对齐 Playbook语法检测与执行 Playbook任务实施 Playbook特权升级 Playbook常用模块 软件包管理模块 用户管理模块 存储模块管理 文件操作相关模块 …

GPT-3 论文阅读笔记

GPT-3模型出自论文《Language Models are Few-Shot Learners》是OpenAI在2020年5月发布的。 论文摘要翻译&#xff1a;最近的工作表明&#xff0c;通过对大量文本进行预训练&#xff0c;然后对特定任务进行微调&#xff08;fine-tuning)&#xff0c;在许多NLP任务和基准测试上…

TYPE-C口是怎么样的接口?它有什么功能强大的地方?

C口指的是USBType-C接口。USBType-C&#xff0c;又称USB-C&#xff0c;是一种通用串行总线(USB)的硬件接口形式&#xff0c;外观上最大特点在于其上下端完全一致与Micro-USB相比不再区分USB正反面。 认识了Type-C的外观之后&#xff0c;我们来一起看一下它是怎么产生的。早在20…

QT with OpenGL(IBL-镜面反射)

文章目录 预滤波generate Mipmap获取每一层级的预滤波图prefilterMap Shader重要性采样效果展示 预过滤卷积的亮点解决方法代码解析首先得确保我们被采样的环境贴图有mipmap贴图通过计算决定使用那一层mipmap值 效果 预计算BRFD生成LUT图 IBL Shading渲染结果与教材的不同最终结…

(C语言版)力扣(LeetCode)189. 轮转数组官方3种解法分析

轮转数组 题目第一种解法&#xff1a;额外数组第二种解法&#xff1a;环状替换第三种解法&#xff1a;翻转数组结语 题目 题目链接&#xff1a;轮转数组 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: num…

实战项目:手把手带你实现一个高并发内存池

项目介绍 1.这个项目做的是什么&#xff1f; 当前项目是实现一个高并发的内存池&#xff0c;他的原型是google的一个开源项目tcmalloc&#xff0c;tcmalloc全称Thread-Caching Malloc&#xff0c;即线程缓存的malloc&#xff0c;实现了高效的多线程内存管理&#xff0c;用于替…

Java——字符串的排列

题目链接 牛客网在线oj题——字符串的排列 题目描述 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数…

【SpringMVC】| SpringMVC 入门

目录 一&#xff1a;SpringMVC 入门 1. SpringMVC简介 2. SpringMVC的优点 3. SpringMVC的优化 4. SpringMVC执行的流程 5. 基于注解的SpringMVC程序 图书推荐 一&#xff1a;《Spring Boot进阶&#xff1a;原理、实战与面试题分析》 二&#xff1a;《深入理解Java虚拟…

19.网络爬虫—照片管道

网络爬虫—照片管道 Scrapy基础Scrapy运行流程原理Scrapy的工作流程 scrapy照片管道实战演示设置图片路径配置爬虫解析数据运行爬虫查看文件 后记 前言&#xff1a; &#x1f3d8;️&#x1f3d8;️个人简介&#xff1a;以山河作礼。 &#x1f396;️&#x1f396;️:Python领域…

C++ Primer笔记——排列算法(next_permutation、prev_permutation、is_permutation)

目录 概述 ①next_permutation ②prev_permutation ③is_permutation 概述 页数&#xff1a;P778 &#xff08;A.2.7 排列算法&#xff09; 头文件&#xff1a;<algorithm> 函数名&#xff1a;next_permutation & prev_permutation & is_permutation C为…