Linux网络编程之UDP编程

        UDP编程效率高,不需要差错校验,在视频点播场景应用高

基于UDP协议客户端和服务端的编程模型,和TCP模型有点类似,有些发送接收函数不同,TCP是之间调用I/O函数read0或write()进行读写操作,而UDP是用sendto()和readfrom()等封装好了的函数进行数据接收发送

1.UDP服务器端:

socket  填写SOCK_DGRAM

bind(),套接字和地址和端口进行绑定

readfrom()获取接收客户端发送过来的报文,是对read()的封装,也是阻塞性的读写,如果接收不到客户端发送过来的数据报文,就阻塞

 sendto()  向对方发送数据报文,

close()关闭套接字

2.客户端:socket()

1.socket()创建套接字

2.bind(),客户端一般不需要绑定

3.sendto()客户端向服务端发送数据报文

4.readfrom()读取服务端返回的数据报文

5.close()关闭套接字

3.数据传输

1.发送数据   成功调用返回发送字节数,出错返回-1

send()函数,

第一个参数,套接字描述符

第二个参数,发送的内容

第三个,第二个参数占的字节内存

第四个通常为0

sendto()函数,比send()多了两个参数,

第五个传入通用地址结构体,里面封装了接收方地址包括端口信息,目的地的信息

第六个参数,第五个参数的大小

sendmsg()    把发送的数据报文封装在叫做msghdr的结构体中

这个结构体第三个参数,可以把具体的数据报文放在里面

2.接收数据

recv()函数

第一个参数,套接字描述符

第二个参数,接收到的内存

第三个参数,第二个参数大小

第四个,一般设置为0

recvfrom()函数

第五个参数传入通用地址结构体,用来存放发送方的一些地址信息,(接收方接收到发送方发过来的数据报文,接收方这方可用这个结构体存放发送方的地址和占用端口,

第六个参数就是第五个参数占用几个字节

recvmsg()函数

将接收的数据报文都存放在msghdr这个结构体当中

4.基于UDP端的服务器编程

                        客户端连接后,服务端返回一个系统时间

time_udp_server.c

#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <netdb.h>
#include <signal.h>
#include <arpa/inet.h>//UDP服务器端,返回实时时间
//udp是无连接的,不会做应答和差错校验
int sockfd;void sig_handler(int signo)
{if(signo == SIGINT){printf("server close\n");close(sockfd);exit(1);}
}//输出客户端的一些ip和端口信息
void out_addr(struct sockaddr_in *clientaddr)
{char ip[16];int port;memset(ip, 0, sizeof(ip));//网络字节序转换为点分十进制字节序,是字符串形式inet_ntop(AF_INET, &clientaddr->sin_addr.s_addr, ip, sizeof(ip));port = ntohs(clientaddr->sin_port);printf("client: %s(%d)\n", ip, port);}//负责和客户端进行通讯
void do_service(int fd)
{struct sockaddr_in clientaddr;socklen_t len =sizeof(clientaddr);char buffer[1024];  //缓存memset(buffer, 0, sizeof(buffer));//接收客户端信息,传送的地址结构体用来接收//发送方的地址信息if(recvfrom(sockfd, buffer, sizeof(buffer),0, (struct sockaddr*)&clientaddr, &len) < 0){perror("recvfrom error");}else{out_addr(&clientaddr);//输出客户端的一些相关信息printf("client send into: %s\n",buffer);//向客户端发送数据报文//t为1970年经过的秒数long int t = time(0);//ctime输入秒数,返回现在时间//的字符串char *ptr = ctime(&t);size_t size = strlen(ptr) * sizeof(char);if(sendto(sockfd, ptr, size, 0, (struct sockaddr*)&clientaddr, len) < 0){perror("sendto error");}}}int main(int argc, char *argv[])
{struct timeval timeout;//超时结构体timeout.tv_sec = 10;  // 10 秒timeout.tv_usec = 0;  // 0 微秒if(argc < 2){printf("usage: %s port\n", argv[0]);exit(1);}if(signal(SIGINT, sig_handler) == SIG_ERR){perror("signal sigint error\n");exit(1);}/*步骤1:创建socket*/sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd < 0){perror("socket error\n");exit(1);}/*设置套接字相关选项,服务器停掉,启动服务器端会在指定端口监听,如果服务器断掉监听的端口不会马上使用,把服务器停掉后这些端口能够马上使用,我们最好设置套接字的选项*///udp服务器端设置超时设置int ret;int opt = 1;  //打开//设置套接字的选项,第二个参数表明是通用的套接字层次选项//第三个参数表明设置端口停掉后,下次重新绑定这个端口//这个端口可以重新继续使用if((ret = setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR, &opt, sizeof(opt))) < 0){perror("setsocketopt erroe");exit(1);}//设置接收超时设置10sret = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const void *)&timeout, sizeof(timeout));if (ret < 0) {perror("setsockopt SO_RCVTIMEO error");close(sockfd);exit(1);}/*步骤2:调用bind函数对socket和地址进行绑定*/struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET; //IPV4serveraddr.sin_port = htons(atoi(argv[1]));  //端口serveraddr.sin_addr.s_addr = INADDR_ANY;  //获得所有ip请求if(bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr))<0){perror("bind error");exit(1);}/*步骤3,和客户端进行双向数据通信*/while(1){do_service(sockfd);}
}

time_udp_client.c

#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <netdb.h>
#include <signal.h>
#include <arpa/inet.h>int sockfd;void sig_handler(int signo)
{if(signo == SIGINT){printf("client close\n");close(sockfd);exit(0);}
}//udp端客户端程序
//步骤1创建,绑定,读写,发送和接收数据报文int main(int argc, char *argv[])
{if(argc < 3){printf("usage: %s ip port\n", argv[0]);exit(0);}if(signal(SIGINT, sig_handler) == SIG_ERR){perror("signal error");exit(1);}/*步骤1:创建socket*/sockfd = socket(AF_INET, SOCK_DGRAM, 0);if(sockfd < 0){perror("socket error");exit(1);}/*步骤2:调用recvfrom和sendto函数和服务器进行双向通信*///定义服务端的结构体地址struct sockaddr_in serveraddr;memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(atoi(argv[2]));//点分十进制转换为网络字节序inet_pton(AF_INET, argv[1], &serveraddr.sin_addr.s_addr);//客户端向服务端发送数据报文//要向服务器发送的内容//在udp编程中,能否调用connect//在tcp中调用connect经过三次握手//在udp中调用connect后内核中记录了服务器端//的地址信息,包括了服务器端ip和端口//调用了connect后,可以用send(),而不是sendto()//if(connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0){perror("connect error");exit(1);}char buffer[1024] = "hello iotek";//if(sendto(sockfd, buffer, sizeof(buffer), 0//    , (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0){//调用了connect内核中记录了服务器的地址和端口,发送时会自动发给内核记录地址if(send(sockfd, buffer, sizeof(buffer), 0) < 0){perror("sendto error");exit(1);}else{//如果成功发送,接收服务器发送报文memset(buffer, 0, sizeof(buffer));size_t size;//开始接收服务方发送返回信息//recv和recvfrom()都是阻塞性的//调用connect成功后,接收会接收connect好的地址的报文if((size = recv(sockfd, buffer,sizeof(buffer), 0)) < 0){perror("recv error");exit(1);}else{ //成功接收,显示到标准输出printf("%s\n", buffer);}}return 0;
}

运行结果:

服务端

客户端:

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

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

相关文章

【C++动态规划 01背包】2787. 将一个数字表示成幂的和的方案数|1817

本文涉及知识点 C动态规划 C背包问题 LeetCode2787. 将一个数字表示成幂的和的方案数 给你两个 正 整数 n 和 x 。 请你返回将 n 表示成一些 互不相同 正整数的 x 次幂之和的方案数。换句话说&#xff0c;你需要返回互不相同整数 [n1, n2, …, nk] 的集合数目&#xff0c;满…

服务器开放了mongodb数据库的外网端口,但是用mongodbCompass还是无法连接。

数据库的配置文件中有个bingIp也就是绑定固定的ip才能访问数据库&#xff0c;默认是127.0.0.1也就是只能本地访问&#xff0c;所以无法连接。设置为0.0.0.0则表示所有地址都能访问。 最后再确定一下防火墙的端口是否正常开放

《Linux运维总结:基于银河麒麟V10+ARM64架构CPU部署redis 6.2.14 TLS/SSL哨兵集群》

总结:整理不易,如果对你有帮助,可否点赞关注一下? 更多详细内容请参考:《Linux运维篇:Linux系统运维指南》 一、简介 Redis 哨兵模式是一种高可用性解决方案,它通过监控 Redis 主从架构,自动执行故障转移,从而确保服务的连续性。哨兵模式的核心组件包括哨兵(Sentine…

JDK1.5 java代码打包jar HmacSha256

文章目录 demo地址背景实现编写代码编译class文件打包 JAR 文件执行生成的 JAR 文件辅助验证方式 常见问题和解决方法常规生成jar方案maven插件idea工具 demo地址 https://github.com/xiangge-zx/HmacSha256 背景 最近接到一个需求,做一个可以用来HmacSha256加密的小工具&am…

数据结构与算法分析:专题内容——动态规划1之理论讲解(代码详解+万字长文+算法导论+力扣题)

一、前言 The future is independent of the past given the present 未来独立于过去&#xff0c;只基于当下。 马尔可夫链&#xff0c;即状态空间中经过从一个状态到另一个状态的转换的随机过程。 0 在开始之前请认真理解下面这段话&#xff1a; 决策类求最优解问题&#xf…

25.停车场管理系统(基于web的Java项目)

目录 1.系统的受众说明 2.相关技术与方法 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 需求分析 3.2.1 系统功能描述 3.2.2 用例图分析 4. 系统设计 4.1 系统类分析 5. 系统详细设计与实现 5.1 用户登录 5.2 系统信…

【网络】自定义协议——序列化和反序列化

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是序列化和分序列&#xff0c;并且自己能手撕网络版的计算器。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不…

.NET 8 中 Entity Framework Core 的使用

本文代码&#xff1a;https://download.csdn.net/download/hefeng_aspnet/89935738 概述 Entity Framework Core (EF Core) 已成为 .NET 开发中数据访问的基石工具&#xff0c;为开发人员提供了强大而多功能的解决方案。随着 .NET 8 和 C# 10 中引入的改进&#xff0c;开发人…

Docker学习—Docker的安装与使用

Docker安装 1.卸载旧版 首先如果系统中已经存在旧的Docker&#xff0c;则先卸载&#xff1a; yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine2.配置Docker的yum库 首先…

ArcGIS006:ArcMap常用操作151-200例动图演示

摘要&#xff1a;本文介绍了ArcMap邻域分析、栅格表面分析、水文分析、区域分析、提取分析等工具箱中的工具功能。包括计算图层间点、线、面要素间的距离、位置和角度&#xff0c;创建缓冲区&#xff0c;添加计算信息到属性表&#xff0c;分割面要素&#xff0c;编号&#xff0…

小菜家教平台(三):基于SpringBoot+Vue打造一站式学习管理系统

目录 前言 今日进度 详细过程 相关知识点 前言 昨天重构了数据库并实现了登录功能&#xff0c;今天继续进行开发&#xff0c;创作不易&#xff0c;请多多支持~ 今日进度 添加过滤器、实现登出功能、实现用户授权功能校验 详细过程 一、添加过滤器 自定义过滤器作用&…

SQL进阶技巧:如何计算复合增长率?

目录 0 场景描述 1 数据准备 2 问题分析 3 小结 0 场景描述 复合增长率是第N期的数据除以第一期的基准数据&#xff0c;然后开N-1次方再减去1得到的结果。假如2018年的产品销售额为10000&#xff0c;2019年的产品销售额为12500&#xff0c;2020年的产品销售额为15000&…

python-docx -- 读取word图片

文章目录 概念介绍形状对象读取图片自定义图形 概念介绍 从概念上来讲&#xff0c;word文档分为两层&#xff0c;一个文本层&#xff0c;一个绘画层&#xff1b; 文本层&#xff0c;从上到下&#xff0c;从左到右&#xff0c;流式排版&#xff0c;本页填满则开启新页面&#…

Python数据可视化seaborn

产品经理在做数据分析时可能需要通过可视化来分析。seaborn官网 1. relplot 散点图 https://seaborn.pydata.org/examples/scatterplot_sizes.html import pandas as pd import seaborn as sns df pd.DataFrame({x: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],y: [8, 6, 7, 8, 4, 6,…

释放专利力量:Patently 如何利用向量搜索和 NLP 简化协作

作者&#xff1a;来自 Elastic Matt Scourfield, Andrew Crothers, Brian Lambert 组织依靠知识产权 (IP) 来推动创新、保持竞争优势并创造收入来源。对于希望将新产品推向市场的公司来说&#xff0c;弄清楚谁拥有哪些专利是一项必不可少的能力。搜索数百万项专利可能既困难又耗…

协议栈攻击分类(CISP-PTE笔记)

CISP-PTE笔记 协议栈攻击分类 1.协议栈自身的脆弱性 ​ 1&#xff09;缺乏数据源验证机制 ​ 2&#xff09;缺乏完整性验证机制 ​ 3&#xff09;缺乏机密性验证机制 2.网络接口层攻击 3.网络层攻击 4.应用层攻击 网络攻击的基本模式 被动威胁&#xff08;不影响通信双…

SpringBoot3集成Junit5

目录 1. 确保项目中包含相关依赖2. 配置JUnit 53. 编写测试类4、Junit5 新增特性4.1 注解4.2 断言4.3 嵌套测试4.4 总结 在Spring Boot 3中集成JUnit 5的步骤相对简单。以下是你可以按照的步骤&#xff1a; 1. 确保项目中包含相关依赖 首先&#xff0c;确保你的pom.xml文件中…

智慧城市智慧城市项目方案-大数据平台建设技术方案(原件Word)

第1章 总体说明 1.1 建设背景 1.2 建设目标 1.3 项目建设主要内容 1.4 设计原则 第2章 对项目的理解 2.1 现状分析 2.2 业务需求分析 2.3 功能需求分析 第3章 大数据平台建设方案 3.1 大数据平台总体设计 3.2 大数据平台功能设计 3.3 平台应用 第4章 政策标准保障…

算法练习:904. 水果成篮

题目链接&#xff1a;904. 水果成篮。 题目意思就是可以选取两个种类的水果不能超过两个种类&#xff0c;该种类个数没有限制&#xff0c; 但是一旦超过两个种类的水果就要停止计数。 示例中数组编号就是就是种类&#xff0c;就是不能出现三个不同编号的数。 1.暴力解法&…

wincc中全局脚本C(c语言脚本)的研究和解密

文章目录 前言一、分析 前言 很多时候我们在wincc中写全局脚本时会为自己的脚本添加密码&#xff0c;但很久很久以后再想修改密码忘记了怎么办呢。 一、分析 经过分析编码有了下面成功 ![请添加图片描述](https://i-blog.csdnimg.cn/direct/33baf91a49da410e82f16b4fbd746c48…