Linux——网络(udp)
文章目录
目录
文章目录
前言
一、upd函数及接口介绍
1. 创建套接字 - socket 函数
2. 绑定地址和端口 - bind 函数
3. 发送数据 - sendto 函数
4. 接收数据 - recvfrom 函数
5. 关闭套接字 - close 函数
二、代码示例
1.服务端
2.客户端
总结
前言
Linux——网络基础(1)-CSDN博客
一、upd函数及接口介绍
1. 创建套接字 - socket
函数
#include <sys/socket.h>int socket(int domain, int type, int protocol);
- 参数说明:
domain
:指定协议族,对于 UDP 编程,通常使用AF_INET
表示 IPv4 协议族。type
:指定套接字类型,对于 UDP,使用SOCK_DGRAM
表示数据报套接字。protocol
:指定具体的协议,一般设置为 0,让系统自动选择合适的协议(对于SOCK_DGRAM
通常为 UDP)。
- 返回值:
- 成功时返回一个非负的套接字描述符;失败时返回 -1,并设置
errno
以指示错误类型。
- 成功时返回一个非负的套接字描述符;失败时返回 -1,并设置
2. 绑定地址和端口 - bind
函数
#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 参数说明:
sockfd
:由socket
函数返回的套接字描述符。addr
:指向sockaddr
结构体的指针,该结构体包含要绑定的地址和端口信息。对于 IPv4,通常使用sockaddr_in
结构体,并进行强制类型转换。addrlen
:addr
结构体的长度。
- 返回值:
- 成功时返回 0;失败时返回 -1,并设置
errno
。
- 成功时返回 0;失败时返回 -1,并设置
3. 发送数据 - sendto
函数
#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
:套接字描述符。buf
:指向要发送数据的缓冲区。len
:要发送数据的长度。flags
:发送标志,通常设置为 0。dest_addr
:指向目标地址的sockaddr
结构体指针,包含目标主机的地址和端口信息。addrlen
:dest_addr
结构体的长度。
- 返回值:
- 成功时返回实际发送的字节数;失败时返回 -1,并设置
errno
。
- 成功时返回实际发送的字节数;失败时返回 -1,并设置
4. 接收数据 - recvfrom
函数
#include <sys/socket.h>ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
- 参数说明:
sockfd
:套接字描述符。buf
:指向用于存储接收数据的缓冲区。len
:缓冲区的最大长度。flags
:接收标志,通常设置为 0。src_addr
:指向源地址的sockaddr
结构体指针,用于存储发送方的地址和端口信息。addrlen
:指向src_addr
结构体长度的指针,调用前设置为该结构体的大小,调用后会被更新为实际接收到的地址信息的长度。
- 返回值:
- 成功时返回实际接收的字节数;失败时返回 -1,并设置
errno
。
- 成功时返回实际接收的字节数;失败时返回 -1,并设置
5. 关闭套接字 - close
函数
#include <unistd.h>int close(int fd);
- 参数说明:
fd
:要关闭的套接字描述符。
- 返回值:
- 成功时返回 0;失败时返回 -1,并设置
errno
。
- 成功时返回 0;失败时返回 -1,并设置
二、代码示例
1.服务端
#pragma once#include <iostream>
#include <string>
#include <strings.h>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
#include "Log.hpp"// using func_t = std::function<std::string(const std::string&)>;
typedef std::function<std::string(const std::string&)> func_t;Log lg;enum{SOCKET_ERR=1,BIND_ERR
};uint16_t defaultport = 8080;
std::string defaultip = "0.0.0.0";
const int size = 1024;class UdpServer{
public:UdpServer(const uint16_t &port = defaultport, const std::string &ip = defaultip):sockfd_(0), port_(port), ip_(ip),isrunning_(false){}void Init(){// 1. 创建udp socketsockfd_ = socket(AF_INET, SOCK_DGRAM, 0); // PF_INETif(sockfd_ < 0){lg(Fatal, "socket create error, sockfd: %d", sockfd_);exit(SOCKET_ERR);}lg(Info, "socket create success, sockfd: %d", sockfd_);// 2. bind socketstruct sockaddr_in local;bzero(&local, sizeof(local));local.sin_family = AF_INET;local.sin_port = htons(port_); //需要保证我的端口号是网络字节序列,因为该端口号是要给对方发送的local.sin_addr.s_addr = inet_addr(ip_.c_str()); //1. string -> uint32_t 2. uint32_t必须是网络序列的 // ??// local.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(sockfd_, (const struct sockaddr *)&local, sizeof(local)) < 0){lg(Fatal, "bind error, errno: %d, err string: %s", errno, strerror(errno));exit(BIND_ERR);}lg(Info, "bind success, errno: %d, err string: %s", errno, strerror(errno));}void Run(func_t func) // 对代码进行分层{isrunning_ = true;char inbuffer[size];while(isrunning_){struct sockaddr_in client;socklen_t len = sizeof(client);ssize_t n = recvfrom(sockfd_, inbuffer, sizeof(inbuffer) - 1, 0, (struct sockaddr*)&client, &len);if(n < 0){lg(Warning, "recvfrom error, errno: %d, err string: %s", errno, strerror(errno));continue;}inbuffer[n] = 0;std::string info = inbuffer;std::string echo_string = func(info);sendto(sockfd_, echo_string.c_str(), echo_string.size(), 0, (const sockaddr*)&client, len);}}~UdpServer(){if(sockfd_>0) close(sockfd_);}
private:int sockfd_; // 网路文件描述符std::string ip_; // 任意地址bind 0uint16_t port_; // 表明服务器进程的端口号bool isrunning_;
};
Init
方法用于初始化 UDP 服务器:- 调用
socket
函数创建一个 UDP 套接字,使用AF_INET
表示 IPv4 协议族,SOCK_DGRAM
表示 UDP 套接字。 - 如果套接字创建失败,使用日志记录错误信息并退出程序。
- 创建一个
sockaddr_in
结构体local
,用于存储服务器的地址信息。 - 使用
bzero
函数将local
结构体清零。 - 设置
local
结构体的sin_family
为AF_INET
,sin_port
为传入的端口号,并使用htons
函数将其转换为网络字节序。 - 使用
inet_addr
函数将传入的 IP 地址字符串转换为网络字节序的 32 位整数,并赋值给sin_addr.s_addr
。 - 调用
bind
函数将套接字绑定到指定的地址和端口。 - 如果绑定失败,使用日志记录错误信息并退出程序。
- 调用
Run
方法用于启动 UDP 服务器并处理客户端请求:- 将
isrunning_
标志设置为true
,表示服务器正在运行。 - 创建一个大小为
size
的字符数组inbuffer
,用于存储接收到的数据。 - 进入一个无限循环,不断接收客户端发送的数据。
- 调用
recvfrom
函数接收客户端发送的数据,并将客户端的地址信息存储在client
结构体中。 - 如果接收失败,使用日志记录错误信息并继续下一次循环。
- 在接收到的数据末尾添加字符串结束符
'\0'
,将其转换为std::string
类型的info
。 - 调用传入的函数对象
func
对接收到的数据进行处理,并将处理结果存储在echo_string
中。 - 调用
sendto
函数将处理结果发送回客户端。
- 将
2.客户端
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>using namespace std;void Usage(std::string proc)
{std::cout << "\n\rUsage: " << proc << " serverip serverport\n"<< std::endl;
}// ./udpclient serverip serverport
int main(int argc, char *argv[])
{if (argc != 3){Usage(argv[0]);exit(0);}std::string serverip = argv[1];uint16_t serverport = std::stoi(argv[2]);struct sockaddr_in server;bzero(&server, sizeof(server));server.sin_family = AF_INET;server.sin_port = htons(serverport); //?server.sin_addr.s_addr = inet_addr(serverip.c_str());socklen_t len = sizeof(server);int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){cout << "socker error" << endl;return 1;}// client 要bind吗?要!只不过不需要用户显示的bind!一般有OS自由随机选择!// 一个端口号只能被一个进程bind,对server是如此,对于client,也是如此!// 其实client的port是多少,其实不重要,只要能保证主机上的唯一性就可以!// 系统什么时候给我bind呢?首次发送数据的时候string message;char buffer[1024];while (true){cout << "Please Enter@ ";getline(cin, message);// std::cout << message << std::endl;// 1. 数据 2. 给谁发sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, len);struct sockaddr_in temp;socklen_t len = sizeof(temp);ssize_t s = recvfrom(sockfd, buffer, 1023, 0, (struct sockaddr*)&temp, &len);if(s > 0){buffer[s] = 0;cout << buffer << endl;}}close(sockfd);return 0;
}
argc
表示命令行参数的数量,argv
是一个字符串数组,存储了命令行参数。- 如果命令行参数数量不等于 3(程序名、服务器 IP 地址、服务器端口号),则调用
Usage
函数打印使用说明并退出程序。 - 从命令行参数中获取服务器的 IP 地址和端口号。
std::stoi
函数将字符串类型的端口号转换为uint16_t
类型。- 创建一个
sockaddr_in
结构体server
,用于存储服务器的地址信息。 bzero
函数将server
结构体的内存清零。server.sin_family
设置为AF_INET
,表示使用 IPv4 地址族。server.sin_port
使用htons
函数将端口号从主机字节序转换为网络字节序。server.sin_addr.s_addr
使用inet_addr
函数将字符串类型的 IP 地址转换为网络字节序的 32 位整数。len
存储server
结构体的大小。socket
函数创建一个 UDP 套接字,使用AF_INET
表示 IPv4 地址族,SOCK_DGRAM
表示 UDP 协议。- 如果套接字创建失败,输出错误信息并返回 1。
- 创建一个
std::string
类型的message
用于存储用户输入的消息,创建一个字符数组buffer
用于存储从服务器接收的数据。 - 使用
getline
函数从标准输入读取用户输入的消息。 sendto
函数将消息发送给服务器,指定套接字描述符、消息内容、消息长度、标志位、服务器地址结构体和地址结构体的大小。- 创建一个
sockaddr_in
结构体temp
用于存储服务器的地址信息,len
存储temp
结构体的大小。 recvfrom
函数从服务器接收数据,指定套接字描述符、接收缓冲区、缓冲区大小、标志位、服务器地址结构体指针和地址结构体大小指针。- 如果接收到的数据长度大于 0,在缓冲区末尾添加字符串结束符
'\0'
,并输出接收到的数据。
总结
该程序实现了一个简单的 UDP 客户端,通过命令行参数指定服务器的 IP 地址和端口号,从用户输入获取消息并发送给服务器,同时接收服务器的响应并输出。客户端不需要显式绑定端口,操作系统会在首次发送数据时自动分配一个可用的端口。
相关文章:

Linux——网络(udp)
文章目录 目录 文章目录 前言 一、upd函数及接口介绍 1. 创建套接字 - socket 函数 2. 绑定地址和端口 - bind 函数 3. 发送数据 - sendto 函数 4. 接收数据 - recvfrom 函数 5. 关闭套接字 - close 函数 二、代码示例 1.服务端 2.客户端 总结 前言 Linux——网络基础…...

Oracle-Java JDBC 连接超时之后的认知纠正
背景 偶然读到熊老师的文章《老熊的三分地-JDBC中语句超时与事务》了解到:JAVA代码的最后正常断开数据库连接,在默认情况下,正常断开的数据库连接会自动提交没有提交的事务。 通过文章的测试JAVA程序,可以表明,JDB…...
自定义数据集使用框架的线性回归方法对其进行拟合
代码 import torch import numpy as np import torch.nn as nncriterion nn.MSELoss()data np.array([[-0.5, 7.7],[1.8, 98.5],[0.9, 57.8],[0.4, 39.2],[-1.4, -15.7],[-1.4, -37.3],[-1.8, -49.1],[1.5, 75.6],[0.4, 34.0],[0.8, 62.3]])x_data data[:, 0] y_data data…...

15天基础内容-5
day13 【String类、StringBuilder类】 主要内容 String类常用方法【重点】 String类案例【重点】 StringBuilder类【重点】 StringBuilder类常用方法【重点: append】 StringBuilder类案例【理解】 第一章String类 1.1 String类的判断方法 String类实现判断功能…...

82,【6】BUUCTF WEB .[CISCN2019 华东南赛区]Double Secret
进入靶场 提到了secret,那就访问 既然这样,那就传参看能不能报错 这个页面证明是有用的 传参长一点就会报错,传什么内容无所谓 所以网站是flask框架写的 有一个颜色深一点,点开看看 rc4加密url编码 import base64 from urllib…...

Android WebView 中网页被劫持的原因及解决方案
文章目录 一、原因分析二、解决方案一览三、解决方案代码案例3.1 使用 HTTPS3.2 验证 URL3.3 禁用 JavaScript3.4 使用安全的 WebView 设置3.5 监控网络请求3.6 使用安全的 DNS 四、案例深入分析4.1 问题4.2 分析 五、结论 在 Android 应用开发中,WebView 是一个常用…...
特朗普政府将开展新网络攻击
近日,特朗普政府已表态:减少物理战争,网络战将代替,以实现美国的全球优势。 特朗普也指示美国网络司令部可以在没有总统批准的情况下开展更广泛行动,尤其是应对一些突发事件,这其实成为了后续美国通过网络…...

快递代取项目Uniapp+若依后端管理
快递接单代取得uniappspringboot项目 实际效果图...

arcgis短整型变为长整型的处理方式
1.用QGIS的重构字段工具进行修改,亲测比arcgis的更改字段工具有用 2.更换低版本的arcgis10.2.2,亲测10.5和10.6都有这个毛病,虽然官方文档里面说的是10.6.1及以上 Arcgis10.2.2百度链接:https://pan.baidu.com/s/1HYTwgnBJsBug…...

06、Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等
Redis相关概念:缓存击穿、雪崩、穿透、预热、降级、一致性等 Redis缓存雪崩、缓存击穿、缓存预热热点key、缓存降级、短链接、分布式锁秒杀、预减库存、 堆外缓存Redis架构设计、Redis动态刷新、Redis和DB双写一致性、过期删除策略、集群数据倾斜等一、缓存雪崩 缓…...
嵌入式基础 -- PCIe 控制器中断管理之MSI与MSI-X简介
PCIe 控制器中断管理技术文档 1. 背景 在现代计算机系统中,中断是设备与 CPU 通信的重要机制,PCIe 控制器提供了从传统线中断到基于消息的中断(MSI/MSI-X)的演进,以提升中断处理效率和可扩展性。x86 和 ARM 架构虽然…...

websocket实现
由于安卓资源管理器展示的路径不尽相同,各种软件保存文件的位置也不一定一样.对于普通用户上传文件时,查找文件可能是一个麻烦的事情.后来想到了一个办法,使用pc端进行辅助上传. 文章目录 实现思路1.0 实现定义web与客户端通信数据类型和数据格式web端websocket实现web端对客户…...

unity学习20:time相关基础 Time.time 和 Time.deltaTime
目录 1 unity里的几种基本时间 1.1 time 相关测试脚本 1.2 游戏开始到现在所用的时间 Time.time 1.3 时间缩放值 Time.timeScale 1.4 固定时间间隔 Time.fixedDeltaTime 1.5 两次响应时间之间的间隔:Time.deltaTime 1.6 对应测试代码 1.7 需要关注的2个基本…...

【C++】特殊类设计、单例模式与类型转换
目录 一、设计一个类不能被拷贝 (一)C98 (二)C11 二、设计一个类只能在堆上创建对象 (一)将构造函数私有化,对外提供接口 (二)将析构函数私有化 三、设计一个类只…...

scratch七彩六边形 2024年12月scratch三级真题 中国电子学会 图形化编程 scratch三级真题和答案解析
目录 scratch七彩六边形 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、…...

代码随想录刷题day16|(哈希表篇)349.两个数组的交集
目录 一、哈希表理论基础 二、集合set在哈希法中的应用 三、相关算法题目 四、相关知识点 1.set集合特点和常用方法 1.1 set集合概述 1.2 set集合特点 1.3 常用方法 2.set集合转换成数组 法1:另新建一个数组 法2:将结果集合转为数组 ▲ 3.数组…...

Synology 群辉NAS安装(6)安装mssql
Synology 群辉NAS安装(6)安装mssql 写在前面mssql 2019:成功安装说明,这个最终成功了 mssql 2022没有成功1. pull image2.启动mssql docker container 远程连接 写在前面 mssq是一个重要节点。 这是因为我对mysql没有一丝好感。虽然接触了许…...

2025年美赛B题-结合Logistic阻滞增长模型和SIR传染病模型研究旅游可持续性-成品论文
模型设计思路与创新点: 建模的时候应该先确定我们需要建立什么类的模型?优化类还是统计类?这个题需要大量的数据分析,因此我们可以建立一个统计学模型。 统计学建模思路:观察规律,建立模型,参…...

Hook 函数
什么是hook函数? 在计算机编程中,hook函数是指在特定的事件发生时被调用的函数,用于在事件发生前或后进行一些特定的操作。通常,hook函数作为回调函数被注册到事件处理器中,当事件发生时,事件处理器会自动…...

蓝桥杯模拟算法:蛇形方阵
P5731 【深基5.习6】蛇形方阵 - 洛谷 | 计算机科学教育新生态 我们只要定义两个方向向量数组,这种问题就可以迎刃而解了 比如我们是4的话,我们从左向右开始存,1,2,3,4 到5的时候y就大于4了就是越界了&…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...

K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

[论文阅读]TrustRAG: Enhancing Robustness and Trustworthiness in RAG
TrustRAG: Enhancing Robustness and Trustworthiness in RAG [2501.00879] TrustRAG: Enhancing Robustness and Trustworthiness in Retrieval-Augmented Generation 代码:HuichiZhou/TrustRAG: Code for "TrustRAG: Enhancing Robustness and Trustworthin…...

数据结构:递归的种类(Types of Recursion)
目录 尾递归(Tail Recursion) 什么是 Loop(循环)? 复杂度分析 头递归(Head Recursion) 树形递归(Tree Recursion) 线性递归(Linear Recursion)…...

数据结构:泰勒展开式:霍纳法则(Horner‘s Rule)
目录 🔍 若用递归计算每一项,会发生什么? Horners Rule(霍纳法则) 第一步:我们从最原始的泰勒公式出发 第二步:从形式上重新观察展开式 🌟 第三步:引出霍纳法则&…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...