更新日志

11/06/2021

  • 1.增加IPV6
  • 2.ipv6通过windows10初步测试
  • 3.ipv6包括: 接收和发送
  • 5.增加错误代码接口
  • 6.本机IPv6截图

  • 7.编译通过截图

  • 8.ipv6测试结果

30/05/2021

1.增加IPv6,待测

2.全部改为Unicode编码, 无签名

23-05-2021

1.模块内部增加优化

15/12/2020

  1. cmake重新配置,改为支持modern cmake
  2. 创建cmake文件夹,并创建spdlog.cmake文件
  3. 类的成员函数和成员变量重命名

11/06/2021

  1. 增加IPV6
  2. ipv6通过windows10初步测试

    3.ipv6包括: 接收和发送

    5.增加错误代码接口

30/05/2021

1.增加IPv6,待测

2.全部改为Unicode编码, 无签名

简介

  • 1.这是一个使用C++11语法封装的UDP,包括: ipv4 和 ipv6
  • 2.ipv4支持: 单播、组播、广播; linux + windows10测试通过,接收和发送均成功
  • 3.ipv6通过windows10初步测试。收发均成功; 组播待测
  • 5.支持接收和发送
  • 6.使用cmake管理的项目
  • 7.提供了调用范例
  • 8.Linux支持仔细测试,最近比较忙。 后期更新
  • 9.欢迎留言指导

接口分类

针对使用场景: 初始化, 发送, 接收, 关闭, 如果不接收, 则只有3个接口。 接口函数返回值后面再更新

使用

接收

接收需要重载 iudp.h中的类irecv_data的on_recv_data_函数。 on_recv_data_原型如下:

		///  --------------------------------------------------------------------------------
/// @brief: 接收函数,
/// @param: const unsigned char * pdata_recv - 接收的数据
/// @param: const unsigned int recv_data_len - 接收数据长度
/// @return: void
///
/// --------------------------------------------------------------------------------
virtual void on_recv_data_(const unsigned char *pdata_recv, const unsigned int recv_data_len) = 0;

接收继承范例

  • 你可以在 example/main.cc 中找到下面的代码
  • my_udp继承了类irecv_data类, 并实现函数on_recv_data_
class my_udp : public irecv_data
{
public:
/// ......
/// ...... /// you must override this function to recv data
void on_recv_data_(const unsigned char *pdata_recv, const unsigned int recv_data_len)
{
/// -------------------------------------------------------------------------------
/// 1. recv data
std::cout << "\n --------------AAAAAA data length = " << recv_data_len << "\n";
for (unsigned int i = 0; i < recv_data_len; i++)
{
if (i == 10)
std:: cout << "\n"; std::cout << pdata_recv[i] << ", ";
} std::cout << "\n";
} /// ....

当接收到数据,底层会调用该函数

接收要注意

  • 如果需要接收数据,接口类 iudp 的接口 init_ 的第二个参数需要传递继承自 接口类irecv_dataon_recv_data_ 接口
  • 如果不接收数据,接口类 iudp 的接口 init_ 的第二个参数传递 NULL(或nullptr)即可, 也不需要继承 接口类irecv_data

接口类iudp

  • iudp提供了udp的初始化、发送数据和关闭,提供了接口 error_id_() 获取错误代码
  • 接口返回值详见代码(代码写的比较详细了)
  • 接口尽量设计的简洁

代码

/// ----------------------------------------------------------------------------
/// @brief: UDP接口类
/// ----------------------------------------------------------------------------
class iudp
{
public:
virtual ~iudp(){} /// ------------------------------------------------------------
/// @brief:初始化
/// @param: const udp_param & param - 初始化参数
/// @param: irecv_data * pfunc_recv - 接收对象
/// @return: int
/// 0 - 成功
/// -1 - 失败,param.socket_version_ 传递错误
/// --------------------------------------------------------------
/// ipv4和ipv6错误, 请调用error_id_()获取错误代码
/// 1 - 失败, 端口为0
/// 2 - 失败, 套接字创建失败
/// 3 - 失败,设置发送超时失败
/// 5 - 失败, 设置接收超时失败
/// 6 - 失败, 设置发送缓冲失败
/// 7 - 失败,设置接收缓冲失败
/// 8 - 失败,设置地址宠用失败
/// 9 - 失败, 绑定套接字失败
/// 10 、11、12 - 失败, 设置套接字 组播属性失败
/// 13 - 失败,设置广播失败
/// 15 - 失败,param._cast_type参数值传递错误
/// ------------------------------------------------------------
virtual int init_(const udp_param& param, irecv_data* pfunc_recv /* = nullptr */) = 0; /// ------------------------------------------------------------
/// @brief:发送数据
/// @param: const unsigned char * psend - 待发送数据
/// @param: const unsigned int len_send - 待发送数据长度
/// @return: int
/// -1 - 失败。初始化socket版本错误
/// 0 - 成功
/// 1 - 失败, 参数【psend】为空或 【len_max_send】等于0 或则len_max_send大于发送缓冲区长度(10k)
/// 2 - 失败,套接字创建失败
/// 3 - 失败, 发送数据失败, 请调用error_id_()
/// ------------------------------------------------------------
virtual int send_(const unsigned char* psend, const unsigned int send_len) = 0; /// --------------------------------------------------------------------------------
/// @brief: 关闭
/// @return: int
/// 0 - 成功
/// 其他, 失败
/// --------------------------------------------------------------------------------
virtual int shutdown_() = 0; /// ------------------------------------------------------------
/// @brief:返回错误ID
/// @return: int
///
/// ------------------------------------------------------------
virtual int error_id_() = 0; };

创建和销毁

创建

  • 调用 iudp.h 中的 udp_create_() 可创建iudp。
  • 函数说明
	///  --------------------------------------------------------------------------------
/// @brief: 创建 udp对象
/// @return: lib_udp *
/// NULL- 创建失败
/// != null - 成功
/// --------------------------------------------------------------------------------
lib_udp_api iudp * udp_create_();

销毁

  • 调用 iudp.h 中的udp_release_(iudp* pudp) 可销毁udp_create_创建的对象
  • 函数说明
	///  --------------------------------------------------------------------------------
/// @brief: 释放申请的资源, 内部释放后,见其设置为NULL
/// @param: iudp * pudp - 来自【udp_create_】的创建结果
/// @return: lib_udp_api lib_udp *
/// pudp = NULL
/// --------------------------------------------------------------------------------
lib_udp_api iudp * udp_release_(iudp* pudp);
  • 调用范例
pudp_ = udp_release_(pudp_);

项目地址

giteegithub

接口使用范例

  • 你可以在 example/main.cc中找到下面的代码

代码

接收

/// to recv data, you must inherit udpsocket_recv class
class my_udp : public irecv_data
{
public: /// constructor
my_udp()
{
if (NULL == pudp_)
pudp_ = udp_create_();//// std::unique_ptr<iudp>(lib_udp::udp_create_()).get();
} /// deconstructor
virtual ~my_udp()
{
pudp_ = udp_release_(pudp_);
} /// you must override this function to recv data
void on_recv_data_(const unsigned char *pdata_recv, const unsigned int recv_data_len)
{
/// -------------------------------------------------------------------------------
/// 1. recv data
std::cout << "\n --------------AAAAAA data length = " << recv_data_len << "\n";
for (unsigned int i = 0; i < recv_data_len; i++)
{
if (i == 10)
std:: cout << "\n"; std::cout << pdata_recv[i] << ", ";
} std::cout << "\n";
} /// -------------------------------------------------------------------------------
int init_(udp_param& param)
{
if (pudp_)
return pudp_->init_(param, this); return -20000;
} ///
int send_(const char *psend, const int len_send)
{
if (pudp_)
return pudp_->send_((const unsigned char*)psend, len_send); return -20000;
} ///
int shutdown_()
{
if (pudp_)
return pudp_->shutdown_(); return -20000;
} int error_id_()
{
if (pudp_)
return pudp_->error_id_(); return -20000;
} private:
iudp* pudp_ = NULL;
};

初始化、发送、关闭

	/// -------------------------------------------------------------------------------
/// 1. to prepare params to initialize
udp_param param; param._is_log_debug = false;
param._cast_type = lib_udp::udp_multi_cast;
param._port_dst = 10086;
param._recv_loop = true;
param.socket_version_ = kipv6; #ifdef _WIN32
char arr_ipv4[] = "10.0.0.5";
#elif __linux__
char arr_ipv4[] = "192.168.15.129";
#else
char arr_ipv4[] = "10.1.1.3";
#endif/// std::cout << "local IP = " << arr_ipv4 << std::endl;
char arr_dst[] = "233.0.0.11"; //param.dest_ip_.value_ = std::string(arr_dst);
//param.local_ip_.value_ = std::string(arr_ipv4); std::string str_ipv6;
int indexxxx = 0;
for (auto list_item : ip6_list)
{
str_ipv6 = list_item;
if (3 == indexxxx)
break;
++indexxxx;
} param.dest_ip_.value_ = std::string("FF02::1");
param.local_ip_.value_ = str_ipv6;/// ip6_list.front(); /// -------------------------------------------------------------------------------
/// 1. to create
std::unique_ptr<my_udp> pmy_udp(new(std::nothrow) my_udp); //my_udp* pmy_udp = new(std::nothrow) my_udp; /// failure
if (!pmy_udp)
{
std::cout << "\n my_udp crated failure\n"; #ifdef _WIN32
system("pause");
#endif ///_WIN32
return 0;
} /// -------------------------------------------------------------------------------
/// 2. to initialize udp
int ret = 0;
ret = pmy_udp->init_(param);
if (0 != ret)
{
std::cout << "\ninit error , id = " << ret << ", error id=" << pmy_udp->error_id_() << "\n\n";
ret = pmy_udp->shutdown_();
if (0 != ret)
std::cout << "\nshutdown error , id = " << ret << "\n";
#ifdef _WIN32
system("pause");
#endif ///_WIN32 return 0;
} //pmy_udp->shutdown_(); ////delete pmy_udp;
////pmy_udp = NULL; //return 0; std::cout << "\n init_ip4 success\n"; /// -------------------------------------------------------------------------------
/// 4. to send data
char arr[] = "1234567890";
for (int i = 0; i < 1; i++)
{
int send_len = pmy_udp->send_(arr, strlen(arr));
/// to output the result
std::cout << "udp send, send length = " << send_len << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 1));
} /// to recv data, it needs to rest
std::cout << "\n---------------------------main 1111----------------------------\n";
std::this_thread::sleep_for(std::chrono::milliseconds(1000 * 1));
std::cout << "\n---------------------------main 2222----------------------------\n";
pmy_udp->shutdown_();
std::cout << "\n---------------------------main 3333----------------------------\n";
std::cout << "\nudp has closed\n";

c/c++11封装UDP,支持ipv4和ipv6,支持接收和发送的更多相关文章

  1. [Linux]Linux下开启snmp支持IPV4和IPV6

    SNMP简介 简单网络管理协议(SNMP),由一组网络管理的标准组成,包含一个应用层协议(application layer protocol).数据库模型(database schema)和一组资源 ...

  2. 修改SS配置文件使其同时支持IPV4和IPV6网络

    将/etc/shadowsocks-libev/config.json文件中的 "server":"0.0.0.0", 修改为: "server&qu ...

  3. oracle11G 同时支持IPV4和IPV6配置

    1.修改listener.ora文件 LISTENER = (DESCRIPTION_LIST = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ...

  4. 《网络编程》IPv4 与 IPv6 相互操作

    前言 因为互联网终端不断添加.IPv4 地址长度(32位)已不可以满足要求.所以出现了 IPv6地址(128位).可是现有应用程序大部分还是採用 IPv4 地址形式,所以必须解决 IPv4 与 IPv ...

  5. [Linux]Linux下yaf发送IPV4和IPV6的IPfix

    一.IPFIX与NetFlow 一.IPFIX 全称IP Flow Information Export,即IP流信息输出,是网络流量监测的国际标准.IPFIX是IETF的一个工作组,它的主要工作就是 ...

  6. 《TCP/IP详解卷1:协议》第11章 UDP:用户数据报协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  7. 开源基于asio的网络通信框架asio2,支持TCP,UDP,HTTP,RPC,SSL,跨平台,支持可靠UDP,支持TCP自动拆包,TCP数据报模式等

    开源基于asio的网络通信框架asio2,支持TCP,UDP,HTTP,RPC,SSL,跨平台,支持可靠UDP,支持TCP自动拆包,TCP数据报模式等 C++开发网络通信程序时用asio是个不错的选择 ...

  8. IPv6下网络编程socket, TCP和UDP例子,以及兼容IPV4和IPV6的类

    一.TCP socket ipv6与ipv4的区别 服务器端源代码如下: #include <stdio.h> #include <stdlib.h> #include < ...

  9. NGINX 加载动态模块(NGINX 1.9.11开始增加加载动态模块支持)

    NGINX 1.9.11开始增加加载动态模块支持,从此不再需要替换nginx文件即可增加第三方扩展.目前官方只有几个模块支持动态加载,第三方模块需要升级支持才可编译成模块. tinywan@tinyw ...

随机推荐

  1. Hermite WENO 重构格式

    Hermite WENO 单元重构 本文主要介绍采用 Hermite WENO 重构方法作为斜率限制器应用于二维或高维单元中. 1.简介[1] ENO格式最早由 Harten 等[2]提出,ENO格式 ...

  2. 【豆科基因组】大豆(Soybean, Glycine max)经典文章梳理2010-2020

    目录 2010年1月:大豆基因组首次发表(Nature) 2010年12月:31个大豆基因组重测序(Nature Genetics) 2014年10月:野生大豆泛基因组(Nature Biotechn ...

  3. Jvarkit : Java utilities for Bioinformatics

    Jvarkit : Java utilities for Bioinformatics :一个java写的生物信息工具包:http://lindenb.github.io/jvarkit/

  4. .NET Core如何配置TLS Cipher(套件)?

    前言 前不久我发表了一篇关于TLS协议配置被我钻了空子,经过第三方合作伙伴验证,针对此TLS协议存在不安全套件,急催速速解决,那么我们本篇开始继续整活!第三方合作伙伴对平台安全严苛要求,我们已连续发版 ...

  5. vim文本编辑器的基本使用

    vim文本编辑器的基本使用 1. vi和vim的区别和联系 可以说vim是vi的增强版,在使用vim编辑文本时,可以根据字体颜色来判断编写程序的正确性. 2. vim文本编辑器的常用命令 1. 编辑指 ...

  6. Angular中@Output()的使用方法

    子component中的html文件 <button (click)="Send()">送出</button><br> 子component中的 ...

  7. Android数据存取

    Android数据存取 一.SharedPreferencesc存取数据 SharedPreferences是使用键值对的方式来存储数据的,也就是在保存一条数据时,需要给这条数据提供一个对应的键,这样 ...

  8. Shell学习(十)——du、df命令

    一.du 命令 1.命令格式: du [选项][文件] 2.命令功能: 显示每个文件和目录的磁盘使用空间. 3.命令参数: -a或-all 显示目录中个别文件的大小. -b或-bytes 显示目录或文 ...

  9. Linux学习 - Bash变量

    一.用户自定义变量(本地名) 用户自定义变量只有在当前的shell中生效 1 定义变量 name="zheng huiwei" aa=123 2 变量叠加 aa="$aa ...

  10. BDD自动化测试框架cucumber(1): 最基本的demo

    BDD(Behavior Driven Development),行为驱动开发, 对应自动化测试框架,python有behave,java有cucumber, 这次记录cucumber+springb ...