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

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...

【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...