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了就是越界了&…...

DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式?
DeepSeek-R1解读:纯强化学习,模型推理能力提升的新范式? 1. Impressive Points2. 纯强化学习,LLM推理能力提升新范式?2.1 DeepSeek-R1-Zero2.2 DeepSeek-R1 3. 端侧模型能力提升:蒸馏>强化学习 1. Impre…...

深度解析:基于Vue 3的教育管理系统架构设计与优化实践
一、项目架构分析 1. 技术栈全景 项目采用 Vue 3 TypeScript Tailwind CSS 技术组合,体现了现代前端开发的三大趋势: 响应式编程:通过Vue 3的Composition API实现细粒度响应 类型安全:约60%的组件采用TypeScript编写 原子化…...

【PyTorch】3.张量类型转换
个人主页:Icomi 在深度学习蓬勃发展的当下,PyTorch 是不可或缺的工具。它作为强大的深度学习框架,为构建和训练神经网络提供了高效且灵活的平台。神经网络作为人工智能的核心技术,能够处理复杂的数据模式。通过 PyTorch࿰…...

Spring Boot整合JavaMail实现邮件发送
一. 发送邮件原理 发件人【设置授权码】 - SMTP协议【Simple Mail TransferProtocol - 是一种提供可靠且有效的电子邮件传输的协议】 - 收件人 二. 获取授权码 开通POP3/SMTP,获取授权码 授权码是QQ邮箱推出的,用于登录第三方客户端的专用密码。适用…...

字节跳动发布UI-TARS,超越GPT-4o和Claude,能接管电脑完成复杂任务
每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…...

数据的秘密:如何用大数据分析挖掘商业价值
数据的秘密:如何用大数据分析挖掘商业价值 在这个数据爆炸的时代,我们每天都在产生、存储和处理着海量的数据。然而,仅仅拥有数据并不等于拥有价值。就像拥有一座金矿,不开采和提炼,最终只是一堆毫无用处的石头。如何…...

OAuth1和OAuth2授权协议
OAuth 1 授权协议 1. 概述 OAuth1 是 OAuth 标准的第一个正式版本,它通过 签名和令牌 的方式,实现用户授权第三方访问其资源的功能。在 OAuth1 中,安全性依赖于签名机制,无需传递用户密码。 2. 核心特性 使用 签名(…...

AI学习(vscode+deepseek+cline)
1、网页生成不成功时,直接根据提示让模型替你解决问题 2、http://localhost:3000 拒绝链接时,cmd输入命令InetMgr,网站右键新建-配置你的网页代码物理地址,这里我还输入本机登录名及密码了,并把端口地址由默认80修改为…...

04-机器学习-网页数据抓取
网络爬取(Web Scraping)深度指南 1. 网络爬取全流程设计 一个完整的网络爬取项目通常包含以下步骤: 目标分析: 明确需求:需要哪些数据(如商品价格、评论、图片)?网站结构分析&…...

计网week1+2
计网 一.概念 1.什么是Internet 节点:主机及其运行的应用程序、路由器、交换机 边:通信链路,接入网链路主机连接到互联网的链路,光纤、网输电缆 协议:对等层的实体之间通信要遵守的标准,规定了语法、语义…...