C语言UDP基础CS模型

CS模型UDP流程:

服务器: socket->bind->recvfrom->sendto->close

客户端: socket->sendto->recvfrom->close

代码说明:

1 未使用更先进的服务器模型,用基础单线程阻塞(recvfrom)作为演示

2 服务器使用while循环接收客户端消息

3 适用于同一网段的不同主机间通信 

4 使用SO_REUSEADDR选项消除了测试环境下服务器短时间内无限重启的顾虑

5 运行路径:客户端发射一条消息->服务器收到消息后回射给客户端一条消息->客户端打印出消息

   完成一次基础通信

6 先运行服务器 再运行客户端

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>// 服务器地址
#define SERVER_IP "192.168.142.132"
// 服务器端口
#define SERVER_PORT 55550
// 服务器代码
int main()
{int server_sockfd;struct sockaddr_in server_sockaddr, client_sockaddr;memset(&server_sockaddr, 0, sizeof(server_sockaddr));memset(&client_sockaddr, 0, sizeof(client_sockaddr));socklen_t client_sockaddr_len = sizeof(client_sockaddr);ssize_t send_bytes, recv_bytes;char send_buf[1024] = "server say : give me money.";char recv_buf[1024] = {0};// 创建一个 ipv4 udp 的socketserver_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (server_sockfd == -1){perror("socket");return 1;}// 启用socket选项,避免测试环境中Address already in use// 参数1:已创建的socket 参数2:指定级别 SOL_SOCKET表示适用于套接字本身而非特定协议// 参数3:表示地址及端口可重用 参数4:非0表示启用SO_REUSEADDR 参数5:int的大小4字节// 参数4 和 参数5 的设计目的主要是考虑到未来接口的兼容性int optval = 1;setsockopt(server_sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));// ipv4主机网络序转换inet_pton(AF_INET, SERVER_IP, &server_sockaddr.sin_addr.s_addr);// 端口主机网络序转换server_sockaddr.sin_port = htons(SERVER_PORT);// 指定地址族为ipv4server_sockaddr.sin_family = AF_INET;// 绑定if ((bind(server_sockfd, (struct sockaddr *)&server_sockaddr, sizeof(server_sockaddr))) == -1){perror("bind");close(server_sockfd);return 1;}// 此时可以通过ss -tuln 命令观察到55550 端口的状态为UNCONN(未连接)printf("server start...\n");while (1){// recvfrom函数返回干了3件事// 1 接收数据存到recv_buf 2 将客户端的地址信息存到client_sockaddr 3更新client_sockaddr_len的实际长度recv_bytes = recvfrom(server_sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&client_sockaddr, &client_sockaddr_len);if (recv_bytes == -1){perror("recvfrom");continue;}printf("%s\n", recv_buf);memset(recv_buf, 0, sizeof(recv_buf));// udp是无连接的要向哪发送呢?就是recvfrom返回的客户端地址信息client_sockaddrsend_bytes = sendto(server_sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&client_sockaddr, client_sockaddr_len);if (send_bytes == -1){perror("sendto");continue;}printf("%s\n", send_buf);}// 关闭socket,socket是一个fd所以可以用close关闭if (close(server_sockfd) == -1){perror("close");return 1;}printf("server close...\n");return 0;
}
#define _GNU_SOURCE
#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>// 服务器地址
#define SERVER_IP "192.168.142.132"
// 服务器端口
#define SERVER_PORT 55550
// 客户端
int main()
{int client_sockfd;struct sockaddr_in server_sockaddr;memset(&server_sockaddr, 0, sizeof(server_sockaddr));socklen_t server_sockaddr_len = sizeof(server_sockaddr);ssize_t send_bytes, recv_bytes;char send_buf[1024] = "client say : How can I help you today ?";char recv_buf[1024] = {0};// 建立一个ipv4 udp 的套接字用于客户端client_sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (client_sockfd == -1){perror("socket");return 1;}printf("client start...\n");// 主机网络序转换ip地址并存入server_sockaddr.sin_addr.s_addrinet_pton(AF_INET, SERVER_IP, &server_sockaddr.sin_addr.s_addr);// 主机网络序转换端口并存入server_sockaddr.sin_portserver_sockaddr.sin_port = htons(SERVER_PORT);// 指定地址族为ipv4server_sockaddr.sin_family = AF_INET;// 向服务器发送数据,其中server_sockaddr包含预设的服务器地址信息send_bytes = sendto(client_sockfd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&server_sockaddr, server_sockaddr_len);if (send_bytes == -1){perror("sendto");close(client_sockfd);return 1;}// 打印出来发送内容printf("%s\n", send_buf);// 接收服务器处理后的数据,server_sockaddr表示谁给你发的消息,在此案例中与sendto的server_sockaddr内容相同recv_bytes = recvfrom(client_sockfd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&server_sockaddr, &server_sockaddr_len);if (recv_bytes == -1){perror("recvfrom");close(client_sockfd);return 1;}// 打印消息printf("%s\n", recv_buf);// 关闭客户端socketif (close(client_sockfd) == -1){perror("close");return 1;}printf("client close...\n");return 0;
} // 检查一下客户端

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

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

相关文章

使用 Flink + Faker Connector 生成测试数据压测 MySQL

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

day06vue2学习

day06 路由的封装抽离 问题&#xff1a;所有的路由配置都堆在main.js中不太合适么&#xff1f;不好&#xff0c;会加大代码的复杂度 目标&#xff1a;将路由模块抽离出来。好处&#xff1a;差分模块&#xff0c;利于维护。 大致的做法就是&#xff0c;将路由相关的东西都提…

Python界面库Flet(1)介绍和快速使用

Python界面库Flet(1)快速上手使用 Author&#xff1a;Once Day Date&#xff1a;2024年3月19日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章可参考专栏: Pyt…

【QT+QGIS跨平台编译】之九十:【QGIS_Crashhandler+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、QGIS_Crashhandler介绍二、QGIS下载三、文件分析四、pro文件五、编译实践一、QGIS_Crashhandler介绍 QGIS_Crashhandler模块是QGIS中的一个重要组成部分,它提供了QGIS程序的错误崩溃处理与跟踪。 二、QGIS下载 QGIS网址: QGIS Source Download 获取最新版本的…

RabbitMq高可用

消息队列高级 服务异步通信-高级篇1.消息可靠性1.1.生产者消息确认1.2.消息持久化1.3.消费者消息确认1.4.消费失败重试机制1.5.总结 2.死信交换机2.1.初识死信交换机2.2.TTL2.3.延迟队列 3.惰性队列3.1.消息堆积问题3.2.惰性队列 4.MQ集群4.1.集群分类4.2.普通集群4.3.镜像集群…

Linux shell脚本切换为root用户执行命令

首先安装expect。 sudo apt install expect 创建shell脚本文件&#xff0c;示例内容如下&#xff1a; #!/usr/bin/expectspawn su rootexpect {"密码&#xff1a;" {send "00000\r"}"Password:" {send "000000\r"}}send "./…

【物联网开源平台】tingsboard二次开发环境搭建+编译

文章目录 一&#xff0c;需要准备的环境二&#xff0c;获取tingsboard源码1.git拉取源码2.下载源码压缩包 三.新建仓库存放依赖文件四&#xff0c;编译五&#xff0c;遇到的错误 提示&#xff1a; 1.这篇只要准备两个环境&#xff0c;方法更简单&#xff01; 2.基于tingsboard …

网盘——客户端服务器搭建

1、配置文件加载 资源文件 将服务器IP和PORT信息填入配置文件中 将配置文件作为资源文件添加到资源文件中 程序运行时加载配置文件中的数据 1.1、首先在创建好的代码目录下面创建一个配置文件 代码目录怎么找到的呢&#xff1f; 1.2、在这个路径下面&#xff0c;创建一个…

鸿蒙Harmony应用开发—ArkTS-枚举说明

说明&#xff1a; 本模块首批接口从API version 7开始支持&#xff0c;后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 Color 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 颜色名称颜色值颜色示意Black0x000000 Blue0x0000ff Brown…

STM32 | Systick定时器(第四天)

STM32 第四天 一、Systick定时器 1、定时器概念 定时器:是芯片内部用于计数从而得到时长的一种外设。 定时器定时长短与什么有关???(定时器定时长短与频率及计数大小有关) 定时器频率换算单位:1GHZ=1000MHZ=1000 000KHZ = 1000 000 000HZ 定时器定时时间:计数个数…

NLP 笔记:Latent Dirichlet Allocation (介绍篇)

1 问题介绍 假设我们有一堆新闻&#xff0c;每个新闻都有≥1个主题 我们现在只知道新闻的内容&#xff0c;我们希望一个算法&#xff0c;帮我们把这些新闻分类成主题人类可以根据每个每个文章里面的单词判断主题&#xff0c;那计算机怎么做呢&#xff1f; ——>LDA(Latent D…

利用免费 GPU 部署体验大型语言模型推理框架 vLLM

vLLM简介 vLLM 是一个快速且易于使用的 LLM&#xff08;大型语言模型&#xff09;推理和服务库。 vLLM 之所以快速&#xff0c;是因为&#xff1a; 最先进的服务吞吐量 通过 PagedAttention 高效管理注意力键和值内存 连续批处理传入请求 使用 CUDA/HIP 图快速模型执行 量…

clang-query 的编译安装与使用示例

1&#xff0c;clang query 概述 作用&#xff1a; 检查一个程序源码的抽象语法树&#xff0c;测试 AST 匹配器&#xff1b; 帮助检查哪些 AST 节点与指定的 AST 匹配器相匹配&#xff1b; 2&#xff0c;clang-query 安装 准备&#xff1a; git clone --recursive https://git…

Linux详细介绍

Linux操作系统介绍 Linux 是一种开源的类 Unix 操作系统&#xff0c;最初由 Linus Torvalds 在 1991 年创建。与其他操作系统不同&#xff0c;Linux 是一个基于内核的操作系统&#xff0c;其核心是 Linux 内核。Linux 内核是由程序员社区不断开发和改进的&#xff0c;它提供了…

Exception 语句

上一篇的一元二次方程求根的例子&#xff0c;让我想起了一件事。一元二次方程求根的程序&#xff0c;如果遇到Delta<0&#xff0c;则无解&#xff0c;函数不能返回值。在这个例子中&#xff0c;print打印一条提示信息&#xff0c;然后在求平方根的过程中引发异常。这样处理&…

【 yolo红外微小无人机-直升机-飞机-飞鸟目标检测】

yolo无人机-直升机-飞机-飞鸟目标检测 1. 小型旋翼无人机目标检测2. yolo红外微小无人机-直升机-飞机-飞鸟目标检测3. yolo细分类型飞机-鸟类-无人机检测4. yolo红外大尺度无人机检测5. 小型固定翼无人机检测6. 大型固定翼无人机检测7. yolo航空俯视场景下机场飞机检测 1. 小型…

Hive SQL必刷练习题:排列组合问题【通过join不等式】

排列组合问题【通过join不等式】 这种问题&#xff0c;就是数学的排列不等式&#xff0c;一个队伍只能和其余队伍比一次&#xff0c;不能重复 方法1&#xff1a;可以直接通过join&#xff0c;最后on是一个不等式【排列组合问题的解决方式】 方法2&#xff1a;也可以是提前多加…

IAB欧洲发布首张泛欧洲数字零售媒体能力矩阵图

2024年1月18日&#xff0c;互动广告署-欧洲办事处&#xff08;IAB Europe)发布了首张泛欧洲数字零售媒体能力矩阵图。为媒体买家提供的新资源概述了在欧洲运营的零售商提供的现场、场外和数字店内零售媒体广告机会。 2024年1月18日&#xff0c;比利时布鲁塞尔&#xff0c;欧洲领…

【深度学习】神经网络教程

文章目录 安装python环境熟悉Python安装torch 安装python环境 有解释器&#xff1a; 设置环境&#xff1a; 熟悉Python var1 1 # 整型 var2 1.1 # 浮点型 var3 1 2j # 复数 var4 hello # 字符串 var5 True # 布尔型 var6 [1, 2, 3] # 列表List var7 (1, 2, 3)…

PHP 读取嵌入式数据 SQLite3

SQLite3 属于轻量级开源的嵌入式关系型数据库&#xff0c;但它支持 ACID(Atomicity,Consistency,Isolation,Durability) 事务。 SQLite Download Page: https://www.sqlite.org/download.html 第一步&#xff1a;在 php.ini 中开启 extensionsqlite3 第二步&#xff1a;连接数…