udp网络通信 socket
套接字是实现进程间通信的编程。IP可以标定主机在全网的唯一性,端口可以标定进程在主机的唯一性,那么socket通过IP+端口号就可以让两个在全网唯一标定的进程进行通信。
套接字有三种:
域间套接字:实现主机内部的进程通信的编程
原始套接字:使用网络层或者数据链路层的接口进行编程,更难更底层,例如制作抓包等网络工具
网络套接字:实现用户通信的编程
udp网络通信
服务端server
分析:
服务端最少需要有两个接口,一个用来初始化服务器,一个用来运行服务器
一:初始化服务器接口
创建socket,绑定端口
1.创建socket
socket接口
第一个参数是域,用来确定通信类型
AF_UNIX就是域间套接字,AF_INET/AF_INET6是IPv4/IPv6的网络套接字
第二个参数是传输的数据种类
最常用的是前两个,SOCK_STREAM是面向字节流(TCP),SOCK_DGRAM是面向数据报(UDP)
第三个参数传0即可,这里用不到
返回值返回一个文件描述符
2.绑定端口
bind接口
第一个参数是socket返回的文件描述符
第二个参数是一个包含通信属性的结构体,例如通信域,ip地址和端口号。这是一个输出型参数,而且不同的通信类型的结构体不一样,传参时要进行类型转换。
sockaddr_in有三个成员需要我们初始化:
1.sin_family:通信域,网络通信使用AF_INET
这个成员使用了宏函数,宏传入参数sin_,所以sa_prefix##family等价于sin_family,它是一个无符号短整型
2.sin_port:端口号
端口号会在网络间传输,需要对我们传入的端口号进行处理,使其符合网络字节序,要使用htons()接口
3.sin_addr:ip地址
这个成员是一个结构体,结构体内有一个无符号整形的成员。但是我们一般的ip地址是一个字符串例如(192.168.33.131),所以我们要先将字符串转化为数字,再将数字变为网络字节序。这要用到inet_addr(char*)接口
第三个参数时结构体大小,直接计算即可
注意:一般服务器bind的ip地址是0.0.0.0,如果一个服务是绑定到 0.0.0.0 ,那么外部机器访问该机器上所有 IP 都可以访问该服务。如果服务绑定到的是特定的 ip,则只有访问该 ip 才能访问到服务。
初始化服务器代码样例:
class udpserver{
public:void init(){// 创建udp serversockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){exit(1);}// bind socked//初始化结构体struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(port_); // 转化成网络字节序local.sin_addr.s_addr = inet_addr(ip_.c_str()); // 将ip转化成数字,再将数字转化为网络字节序//bindif (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0){exit(2);}}udpserver(uint16_t port = 8080, string ip = "0.0.0.0"): port_(port), ip_(ip){}~udpserver(){if (sockfd_ > 0)close(sockfd_);}
private:int sockfd_;uint16_t port_;string ip_;
};
二:运行服务器接口
接收数据,对数据做处理,最后发送数据
1.接收数据
recvfrom接口
第一个参数是socket返回的文件描述符,第二个是接收的数据存放的位置,第三个参数是buf空间的大小,第四个参数在本文中这里只要传0即可满足需求。
第五个参数是用来存储数据发送方(客户端)属性的结构体,第六个参数是结构体大小的指针
为什么要记录客户端的通信属性呢?因为服务端在对数据做处理后还要发送回客户端。
2.对数据做处理
需要根据实际需求进行处理,可以通过传函数指针,实现代码分层。见后面的代码示例。
3.发送数据
sendto接口
第一个参数是socket的文件描述符,第二个参数是要发送的数据的地址,第三个参数是发送数据的大小,第四个参数传0。
第五个参数是数据接收方(客户端)属性的结构体,第六个参数是结构体大小。
运行服务器代码样例(包括前面的代码):
//udpserver.hpp
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <functional>
using func = function<string(char*)>;
class udpserver{
public:void init(){// 创建udp serversockfd_ = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd_ < 0){exit(1);}// bind socked//初始化结构体struct sockaddr_in local;local.sin_family = AF_INET;local.sin_port = htons(port_); // 转化成网络字节序local.sin_addr.s_addr = inet_addr(ip_.c_str()); // 将ip转化成数字,再将数字转化为网络字节序//bindif (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0){exit(2);}}void run(func fun){char buf[1024] = {0};while (1){struct sockaddr_in client; // 客户端的信息socklen_t len = sizeof(client);// 收数据ssize_t n = recvfrom(sockfd_, buf, sizeof(buf), 0, (struct sockaddr *)&client, &len);if (n < 0){cout << "receice fail" << endl;continue;}buf[n] = 0;cout << "server get:" << buf << endl;// 处理数据,通过传递的函数实现数据处理的和网络通信解耦string ret = fun(buf);// 发送数据n = sendto(sockfd_, ret.c_str(), ret.size(), 0, (struct sockaddr *)&client, len);}}udpserver(uint16_t port = 8080, string ip = "0,0,0,0"): port_(port), ip_(ip){}~udpserver(){if (sockfd_ > 0)close(sockfd_);}
private:int sockfd_;uint16_t port_;string ip_;
};//main.cpp
#include"udpserver.hpp"
#include<memory>using namespace std;
string datagram(char* data)
{string ret = "Get message:";ret += data;return ret;
}
int main()
{unique_ptr<udpserver> server(new udpserver());server->init();server->run(datagram);return 0;
}
客户端client
分析:
客户端需要初始化客户端,发送数据,接收数据
一:初始化客户端
创建socket和服务端一样,不同的是客户端的bind是操作系统完成的不需要我们操作,客户端会在发送数据时由OS随机bind一个端口。因为客户端的设备可能同时请求多个服务端,例如手机会同时运行很多app,客户端的程序很难为服务端留一个固定的端口(不同公司之间开发软件不可能商量谁要用哪个客户端的端口),而且服务端没必要第一时间知道客户端的端口,客户端发送数据请求时可以获取到客户端的属性
二:发送数据
使用sendto()接口,和服务端一样。
三:接收数据
使用recvfrom()接口,和服务端一样。
客户端代码样例:
#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;
int main(int argc, char *argv[])
{//获取命令行参数,ip和端口号if(argc != 3){cout << "Please input in this way" << endl;cout << "./udpclient" << " [ip]" << " [port]" << endl;}string ip = argv[1];uint16_t port = stoi(argv[2]);// 创建socketint sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0){cout << "client create fail" << endl;}//客户端不需要bind,但是客户端会在发送数据时由OS随机bind一个端口,因为客户端设备同时请求多个服务端,服务端很难让客户端的程序为其留一个固定的端口,而且没必要第一时间知道客户端的端口,客户端发送数据请求时可以获取到// 创建服务端信息的结构体struct sockaddr_in server;server.sin_port = htons(port);server.sin_family = AF_INET;server.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(server);char buf[1024] = {0};string message;while (1){// 发送数据cout << "Please Enter@";getline(cin, message);sendto(sockfd, message.c_str(), message.size(), 0, (struct sockaddr *)&server, len);// 接收数据struct sockaddr_in tem;socklen_t len_tem = sizeof(tem);ssize_t n = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&tem, &len_tem);if (n < 0){cout << "client receive fail" << endl;continue;}buf[n] = 0;cout << buf << endl;}
}
相关文章:

udp网络通信 socket
套接字是实现进程间通信的编程。IP可以标定主机在全网的唯一性,端口可以标定进程在主机的唯一性,那么socket通过IP端口号就可以让两个在全网唯一标定的进程进行通信。 套接字有三种: 域间套接字:实现主机内部的进程通信的编程 …...
LG AI研究开源EXAONE 3.0:一个7.8B双语语言模型,擅长英语和韩语,在实际应用和复杂推理中表现出色
EXAONE 3.0介绍:愿景与目标 EXAONE 3.0是LG AI研究所在语言模型发展中的一个重要里程碑,特别是在专家级AI领域。 “EXAONE”这个名称源自于“ EX pert A I for Every ONE”,反映了LG AI研究所致力于将专家级别的人工智能能力普及化的承诺。这…...

【mysql】mysql之主从部署以及介绍
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...

Invoke-Maldaptive:一款针对LDAP SearchFilter的安全分析工具
关于Invoke-Maldaptive MaLDAPtive 是一款针对LDAP SearchFilter的安全分析工具,旨在用于对LDAP SearchFilter 执行安全解析、混淆、反混淆和安全检测。 其基础是 100% 定制的 C# LDAP 解析器,该解析器处理标记化和语法树解析以及众多自定义属性&#x…...
QT 读取Excel表
一、QAxObject 读取excel表的内容,其仅在windows下生效,当然还有其他跨平台的方案。 config qaxcontainer #include <QAxObject>QStringList GetSheets(const QString& strPath) {QAxObject* excel new QAxObject("Excel.Application&…...
深入理解 Vue 组件样式管理:Scoped、Deep 和 !important 的使用20240909
深入理解 Vue 组件样式管理:Scoped、Deep 和 !important 的使用 在前端开发中,样式的管理与组件化开发之间的平衡一直是一个难题。Vue.js 提供了一些强大的工具来帮助开发者在开发复杂的应用时管理样式。这篇文章将详细介绍 Vue 中的 scoped、:deep() 和…...

C语言内存函数(21)
文章目录 前言一、memcpy的使用和模拟实现二、memmove的使用和模拟实现三、memset函数的使用四、memcmp函数的使用总结 前言 正文开始,发车! 一、memcpy的使用和模拟实现 函数模型:void* memcpy(void* destination, const void* source, size…...
三高基本概念之-并发和并行
并行和并发是计算机科学中两个重要但容易混淆的概念,它们之间的主要区别可以从以下几个方面进行阐述: 一、定义与含义 并行(Parallel):并行是指两个或多个事件在同一时刻发生,即这些事件在微观和宏观上都…...

宝塔面板FTP连接时“服务器发回了不可路由的地址。使用服务器地址代替。”
参考 https://blog.csdn.net/neizhiwang/article/details/106628899 错误描述 我得服务器是腾讯,然后使用宝塔建了个HTML网站,寻思用ftp上传,结果报错: 状态: 连接建立,等待欢迎消息... 状态: 初始化 TLS 中... 状…...
面试的一些小小经验
无论何时,找到合适的满意的工作(距离住处的地理位置,薪资,工作氛围)并不是一件容易的事情。个人能力与职位的适配性永远是有误差的客观存在。 十全十美难得,满足个人的个体化优先级才是客观的存在。 1.投简…...

IV转换放大器原理图及PCB设计分析
【前言】 今天给大家分享一下关于IV转换放大器的相关电路设计心得。IV转换使用的场合非常之多,尤其是电流型输出的传感器,比如光敏二极管、硅光电池等等,这些传感器输出的电流信号非常微弱,我们如果需要检测它们,首先得…...
【数学建模经验贴】一个研赛数模老手的经验
我(非C君,是一个朋友)参加了3次“深圳杯”数模,1次全国大学生数模,以及1次全国研究生数模,2016年参加了全国研究生数模的交流会,但没有参加过美赛,应该算是一个江湖老手了吧。下面内…...

vivo手机已删除的短信还能恢复吗?
虽然现在我们很少使用vivo手机的短信功能,但是我们偶尔还会通过vivo手机短信功能接收一些重要的信息。如果我们在清理垃圾短信的时候误删了vivo手机重要短信,该怎么恢复呢? 方法一:通过vivo云服务恢复 1、确保您已开启vivo云服务…...
[网络][CISCO]CISCO IOS升级
CISCO IOS升级-(转)2008-06-27 15:35IOS 升级 在介绍CISCO路由器IOS升级方法前,有必要对Cisco路由器的存储器的相关知识作以简单介绍。路由器与计算机相似,它也有内存和操作系统。在Cisco路由器中,其操作系统叫做互连…...

通过python提取PDF文件指定页的图片
整体思路 要从 PDF 文件中提取指定页和指定位置的图片,可以分几个步骤来实现: 1.1 准备所需工具与库 在 Python 中处理 PDF 和图像时,需要使用几个库: PyMuPDF (fitz):用于读取和处理 PDF 文件,可以精确…...
Leetcode Hot 100刷题记录 -Day12(轮转数组)
轮转数组 问题描述: 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4]解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向…...
GitHub每日最火火火项目(9.13)
以下是对这些项目的详细介绍: fishaudio 的 fish-speech: 基本信息:这是一种全新的语音技术解决方案,属于文本到语音(Text-to-Speech,TTS)技术范畴。技术特点: 多语言支持ÿ…...
力扣--649.Dota2参议院
Dota2 的世界里有两个阵营:Radiant(天辉)和 Dire(夜魇) Dota2 参议院由来自两派的参议员组成。现在参议院希望对一个 Dota2 游戏里的改变作出决定。他们以一个基于轮为过程的投票进行。在每一轮中,每一位参…...

vim 安装与配置教程(详细教程)
vim就是一个功能非常强大的文本编辑器,可以自己DIY的那种 ,不但可以写代码 ,还可编译 ,可以让你手不离键盘的完成鼠标的所有操作。 如果想要了解vim的的发展历史和详细解说,可以自行上网搜索,我主要是记录一…...
【WPF】Popup的使用
WPF(Windows Presentation Foundation)中的Popup控件用于创建弹出窗口,如工具提示、上下文菜单等。Popup控件本身并不直接显示任何内容,它需要一个子元素来显示实际的内容。 以下是一个简单的XAML示例,展示如何创建一…...

7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...