linuxc语udp发送程序

以下是一个基于UDP通信的C程序,用于发送含有指定格式的数据包。该程序把数据分成若干个包,每个包包含4字节数据包头+数据长度+数据内容,每个包最大8192字节。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>#define MAX_PACKET_SIZE 8192int main() {int sockfd;struct sockaddr_in server_addr;char *data = "Your data goes here.";int data_len = strlen(data);int packet_count = (data_len + MAX_PACKET_SIZE - 1) / MAX_PACKET_SIZE; // calculate total packet countsockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("Error opening socket");exit(1);}memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // set to destination IPserver_addr.sin_port = htons(12345); // set to destination portfor (int i = 0; i < packet_count; i++) {char packet[MAX_PACKET_SIZE + 8]; // 4 bytes header + 4 bytes length + MAX_PACKET_SIZE dataint current_len = (i == packet_count - 1) ? (data_len - i * MAX_PACKET_SIZE) : MAX_PACKET_SIZE; // calculate current packet length*(int*)packet = htonl(0x12345678); // 4 bytes header/**(int*)packet 表示将 packet 的地址强制转换为 int* 类型的指针,并通过解引用操作符 * 获取该地址指向的 int 值。由于 packet 是一个 char 类型数组,对其进行强制类型转换可以让我们将其视为 int 类型的指针,从而访问以 int 为单位的数据。*/*(int*)(packet + 4) = htonl(current_len); // 4 bytes lengthmemcpy(packet + 8, data + i * MAX_PACKET_SIZE, current_len); // datasendto(sockfd, packet, current_len + 8, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); // send packet}close(sockfd);return 0;
}

好的,下面是一个简单的示例代码,演示了发送 UDP 数据包的函数定义以及调用。在这个示例中,我通过一个 send_udp_packets 函数来发送 UDP 数据包,其中除了 int sockfd 之外的其他整数类型都定义为 unsigned int 类型。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>void send_udp_packets(int sockfd, struct sockaddr_in *server_addr, unsigned int custom_header, char *data, unsigned int data_len) {// 构造数据包char packet[1024]; // 假设数据包最大长度为 1024// 填入自定义头部memcpy(packet, &custom_header, sizeof(unsigned int));// 填入数据memcpy(packet + sizeof(unsigned int), data, data_len);// 发送数据包sendto(sockfd, packet, sizeof(unsigned int) + data_len, 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr_in));
}int main() {// 创建 UDP 套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}// 服务器地址struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(12345);  // 假设端口号为 12345server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 假设服务器 IP 地址为 127.0.0.1// 要发送的数据char data[] = "Hello, UDP World!";unsigned int custom_header = 0x12345678; // 自定义头部unsigned int data_len = strlen(data); // 数据长度// 发送数据包send_udp_packets(sockfd, &server_addr, custom_header, data, data_len);// 关闭套接字close(sockfd);return 0;
}

在这个示例中,我们定义了一个 send_udp_packets 函数,它使用 unsigned int 类型来表示自定义头部和数据长度。然后在 main 函数中,我们创建了一个 UDP 套接字,定义了服务器地址和要发送的数据,并最终调用了 send_udp_packets 函数来发送 UDP 数据包。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>#define MAX_PACKET_SIZE 8192void send_udp_packets(int sockfd, struct sockaddr_in *server_addr, char *data, int data_len, unsigned int header1, unsigned int header2, unsigned int header3) {int packet_count = (data_len + MAX_PACKET_SIZE - 1) / MAX_PACKET_SIZE; // 计算总的数据包数量for (int i = 0; i < packet_count; i++) {char packet[MAX_PACKET_SIZE + 12]; // 4字节头部 + 4字节长度 + 3个4字节自定义头部 + MAX_PACKET_SIZE数据int current_len = (i == packet_count - 1) ? (data_len - i * MAX_PACKET_SIZE) : MAX_PACKET_SIZE; // 计算当前数据包长度*(int*)packet = htonl(header1); // 第1个4字节自定义头部*(int*)(packet + 4) = htonl(header2); // 第2个4字节自定义头部*(int*)(packet + 8) = htonl(header3); // 第3个4字节自定义头部*(int*)(packet + 12) = htonl(current_len); // 4字节长度memcpy(packet + 16, data + i * MAX_PACKET_SIZE, current_len); // 数据sendto(sockfd, packet, current_len + 12, 0, (struct sockaddr *)server_addr, sizeof(struct sockaddr)); // 发送数据包}
}int main() {int sockfd;struct sockaddr_in server_addr;char *data = "Your data goes here.";int data_len = strlen(data);unsigned int custom_header1 = 0xabcdef01;unsigned int custom_header2 = 0x12345678;unsigned int custom_header3 = 0xdeadbeef;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("Error opening socket");exit(1);}memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 设置目标IP地址server_addr.sin_port = htons(12345); // 设置目标端口send_udp_packets(sockfd, &server_addr, data, data_len, custom_header1, custom_header2, custom_header3); // 调用发送函数发送数据包unsigned int network_header1 = htonl( custom_header1);printf("htonl(header1): 0x%08x\n", network_header1);close(sockfd);return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>int initialize_udp_socket(struct sockaddr_in *server_addr, int port) {int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("Error opening socket");return -1;}memset(server_addr, 0, sizeof(*server_addr));server_addr->sin_family = AF_INET;server_addr->sin_addr.s_addr = htonl(INADDR_ANY); // 设置目标IP地址server_addr->sin_port = htons(port); // 设置目标端口return sockfd;
}void send_udp_packets(int sockfd, struct sockaddr_in *server_addr, char *data, int data_len, unsigned int header1, unsigned int header2, unsigned int header3) {// 发送数据包的函数保持不变
}int main() {struct sockaddr_in server_addr;char *data = "Your data goes here.";int data_len = strlen(data);int port = 12345;unsigned int custom_header1 = 0xabcdef01;unsigned int custom_header2 = 0x12345678;unsigned int custom_header3 = 0xdeadbeef;int sockfd = initialize_udp_socket(&server_addr, port);if (sockfd == -1) {exit(1);}send_udp_packets(sockfd, &server_addr, data, data_len, custom_header1, custom_header2, custom_header3);close(sockfd);return 0;
}

htonl函数大小端转换:

unsigned int network_header1 = htonl( custom_header1);printf("htonl(header1): 0x%08x\n", network_header1);

htonl(header1): 0x01efcdab

当接收到数据后,您可以使用printf函数将接收到的数据以十六进制形式打印出来。下面
是修改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>#define MAX_PACKET_SIZE 1024void save_to_hex_file(unsigned char *data, unsigned int length) {FILE *file = fopen("received_data.txt", "w");if (file == NULL) {perror("file opening failed");return;}for (unsigned int i = 0; i < length; ++i) {fprintf(file, "%02X ", data[i]);}fclose(file);
}int main() {// 创建 UDP 套接字int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("socket creation failed");exit(EXIT_FAILURE);}// 绑定地址struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY; // 接收所有地址的数据包server_addr.sin_port = htons(12345); // 假设端口号为 12345if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 接收数据unsigned char buffer[MAX_PACKET_SIZE];struct sockaddr_in client_addr;unsigned int len = sizeof(client_addr);int recv_len = recvfrom(sockfd, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&client_addr, &len);if (recv_len < 0) {perror("recvfrom failed");exit(EXIT_FAILURE);}// 打印接收到的数据for (int i = 0; i < recv_len; ++i) {printf("%02X ", buffer[i]);}printf("\n"); // 换行// 保存接收到的数据到文件save_to_hex_file(buffer, recv_len);printf("Received data saved to received_data.txt\n");// 关闭套接字close(sockfd);return 0;
}

在这个修改后的示例中,我添加了一个循环,用于通过printf函数将接收到的数据以十六进制形式打印出来。同时,原有的将数据保存到文件的功能也保留了下来。

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

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

相关文章

华为OD机试真题-小明找位置-2023年OD统一考试(C卷)

题目描述&#xff1a; 小朋友出操&#xff0c;按学号从小到大排成一列&#xff1b;小明来迟了&#xff0c;请你给小明出个主意&#xff0c;让他尽快找到他应该排的位置。 算法复杂度要求不高于nLog(n)&#xff1b;学号为整数类型&#xff0c;队列规模<10000&#xff1b; 输…

持续集成交付CICD:CentOS 7 安装 Nexus 3.63

目录 一、实验 1.CentOS 7 安装Nexus3.63 二、问题 1.安装Nexus报错 2.Nexus启动停止相关命令 一、实验 1.CentOS 7 安装Nexus3.63 &#xff08;1&#xff09;当前操作系统版本&JDK版本 cat /etc/redhat-releasejava -version&#xff08;2&#xff09;下载Nexus新…

蓝桥杯 java基础

1. AB问题I 时间限制&#xff1a;2.000S 空间限制&#xff1a;32MB 题目描述 你的任务是计算ab。 输入描述 输入包含一系列的a和b对&#xff0c;通过空格隔开。一对a和b占一行。 输出描述 对于输入的每对a和b&#xff0c;你需要依次输出a、b的和。 如对于输入中的第二…

面试经典150题(5-7)

leetcode 150道题 计划花两个月时候刷完&#xff0c;今天&#xff08;第二天&#xff09;完成了两道(5-7)150&#xff1a; (169. 多数元素) 题目描述&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋…

int 和 Integer 有什么区别,还有 Integer 缓存的实现

✨前言✨   Java本文主要介绍Java int 和 Integer的区别以及Integer 缓存的实现 &#x1f352;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f352;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 文章目…

用C++实现队列顺序结构的基本操作

//队列顺序结构的基本操作&#xff1a; #include"stdio.h" #include"String" #define QueueSize 100 typedef char ElemType; typedef struct { ElemType data[QueueSize]; /*保存队中元素*/int front,rear; /*队头和队尾指针*/ } SqQueue; void Init…

使用STM32定时器实现精确的时间测量和延时

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进&#xff0c; 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;…

stm32Flash操作

//G0B0 flash大小 0x08000000-0x0807FFFF 512K(0400 1K)//2k 1页 //初始化标记数据地址 放最前面 脱机烧写器可擦除掉 #define CONST_INITMARKDATA_ADDRESS (0x0807D000UL) //2k 1页 //射频数据地址 #define CONST_FREQDATA_ADDRESS (0x0807F000UL) //2…

大数据技术4:Lambda和Kappa架构区别

前言&#xff1a;在大数据处理领域&#xff0c;两种突出的数据架构已成为处理大量数据的流行选择&#xff1a;Lambda 架构和 Kappa 架构。这些架构为实时处理和批处理提供了强大的技术解决方案&#xff0c;使组织能够从其数据中获得有价值的见解。随着互联网时代来临&#xff0…

Python VSCode 配置固定的脚本入口

Python VSCode 配置固定的脚本入口 打开或者新建一个启动配置 选择 .vscode目录下 launch.json文件 将 “program”: “${file}” 替换成 “program”: “mian.py”, //完成你自己的入口.py文件名即可 json启动配置文件 {// Use IntelliSense to learn about possible attrib…

4-redis高级-redis持久化(RDB 持久化方案、AOF持久化、RDB和AOF混合持久化)、redis主从复制

1 redis持久化 1.1 RDB 持久化方案 1.2 AOF持久化 1.3 混合持久化 2 redis主从复制 1 redis持久化 # 把redis数据从内存保存到硬盘上的过程称之为持久化# 所有的数据库&#xff0c;持久化方案快照&#xff1a;某时某刻数据的一个完成备份-mysql的Dump&#xff1a; mysqldump …

【ELK03】ES 索引的Mapping映射详解、数据类型和settings属性设置

一、ES 索引的映射和设置 1.MAPPING 映射(MAPPING)就是es中一个决定了文档如何存储,如何生成索引,字段各种类型定义的过程.类似于我们在关系型数据库中创建一个表格数据之前先定义表格有哪些字段,每个字段是什么类型,然后数据会按照这个配置写入表格,ES中同样是这个过程,它由…

数据结构:顺序表——相关习题2

【2018统考】给定一个含n个整数的数组&#xff0c;设计一个时间上尽可能高效的算法&#xff0c;找到数组中未出现的最小正整数。 void find_min_intnum(int A[],int n){int B[5*n]{0};int i;for (i 0; i < n; i){if(A[i]>0){B[A[i]];}}for(i1;i<5*n;i){if(B[i]0){pr…

面向对象中的单例模式

1、什么是设计模式 设计模式就是前人根据实际的问题提出的问题解决方案&#xff0c;我们把这种就称之为设计模式。 2、单例模式 单例模式是一种常见的设计模式&#xff01; 所谓的设计模式&#xff0c;不是一种新的语法&#xff0c;而是人们在实际的应用中&#xff0c;面对…

【银行测试】金融项目+测试方法范围分析,功能/接口/性能/安全...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、金融行业软件特…

3GPP标准查看、下载和几个UE相关系列标准

由于一直做终端侧协议。最近以UE为核心重新下载了一系列文档。 总结并举例一下分类标准。 如何查看3GPP标准列表 实际上在3GPP网站如下链接&#xff1a;Specifications by Series&#xff0c;每个系列以及分类都说的很清楚。 几个系列分类举例 和终端协议层工作比较关系密切…

如何使用Java Websocket实现实时数据监控功能?

随着互联网应用的不断发展&#xff0c;实时数据监控功能成为了许多应用的必备功能之一。本文将介绍如何使用Java WebSocket实现实时数据监控功能&#xff0c;并提供具体的代码示例。 关键词&#xff1a;Java WebSocket、实时数据监控、代码示例 一、什么是WebSocket&#xff…

ModuleNotFoundError: No module named ‘dlib‘

解决&#xff1a;ModuleNotFoundError: No module named ‘dlib’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named dlib背景报错问题报错翻译报错位置代码报错原因解决方法方法一&#xff0c;直接安装方法二&#xff0c;手动下载安装方法三&#xff0c;编译安…

setuid 的风险及开发过程中的避免方式

使用setuid&#xff08;Set User ID&#xff09;功能将执行程序的有效用户 ID 设置为文件所有者的用户 ID。这意味着执行程序将以文件所有者的特权运行&#xff0c;而不是以执行者自己的特权运行。 尽管setuid是一个有用的功能&#xff0c;但它也会带来一些安全风险。下面是几…

Linux C语言 37- 进程间通信IPC

Linux C语言 37-进程间通信IPC 本节关键字&#xff1a;C语言 进程间通信 信号 管道 消息队列 共享内存 网络通信&#xff08;套接字&#xff09; 相关库函数&#xff1a; 提示&#xff1a;先做内容框架梳理&#xff0c;后期进行完善补充&#xff01; 什么是进程间通信&#…