C/C++ IPV6服务器socket绑定在::,接受ipv4链接(双栈)

先决条件:

1、 创建IPV6套接字

2、打开套接字可重用

3、禁用仅限 IPV6

                BOOL bEnable = FALSE;
                if (setsockopt(listenfd_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&bEnable), sizeof(bEnable)) < 0)
                {
                    return false;
                }
 

4、绑定套接字

5、使用 struct sockaddr_in6 结构接受套接字,而不是用缺省使用 “sockaddr”,否则 10014(WSAEFAULT)错误,并导致套接字句柄泄漏。

                                struct sockaddr_in6 address = { 0 };
                                int address_size = sizeof(address);

                                int sockfd = WSAAccept(listenfd_, (sockaddr*)&address, &address_size, NULL, NULL);
                                if (sockfd != INVALID_SOCKET)
                                {
                                    AcceptSocketEventArgs e = { Adjust(sockfd) };
                                    OnAcceptSocket(e);
                                }

完整大体代码为;

        bool Open(const char* localIP, int localPort, int backlog) noexcept
        {
            if (localPort < IPEndPoint::MinPort || localPort > IPEndPoint::MaxPort)
            {
                return false;
            }

            if (NULL == localIP || *localIP == '\x0')
            {
                return false;
            }

            if (listenfd_ != INVALID_SOCKET)
            {
                return false;
            }

            if (NULL != hEvent_)
            {
                return false;
            }

            if (NULL != afo_)
            {
                return false;
            }

            if (NULL == context_)
            {
                return false;
            }

            boost::system::error_code ec;
            boost::asio::ip::address bindIP = StringToAddress(localIP, ec);
            if (ec)
            {
                return false;
            }

            if (backlog < 1)
            {
                backlog = PPP_LISTEN_BACKLOG;
            }

            in_ = bindIP.is_v4();
            if (bindIP.is_v6())
            {
                struct sockaddr_in6 in6;
                memset(&in6, 0, sizeof(in6));

                in6.sin6_family = AF_INET6;
                in6.sin6_port = htons(localPort);
                if (inet_pton(AF_INET6, localIP, &in6.sin6_addr) < 1)
                {
                    return false;
                }

                listenfd_ = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
                if (listenfd_ == INVALID_SOCKET)
                {
                    return false;
                }

                Adjust(listenfd_);
                if (!Socket::ReuseSocketAddress(listenfd_, true))
                {
                    return false;
                }

                BOOL bEnable = FALSE;
                if (setsockopt(listenfd_, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<char*>(&bEnable), sizeof(bEnable)) < 0)
                {
                    return false;
                }

                if (bind(listenfd_, reinterpret_cast<sockaddr*>(&in6), sizeof(in6)) < 0)
                {
                    return false;
                }
            }
            elif(bindIP.is_v4())
            {
                struct sockaddr_in in4;
                memset(&in4, 0, sizeof(in4));

                in4.sin_family = AF_INET;
                in4.sin_port = htons(localPort);
                if (inet_pton(AF_INET, localIP, &in4.sin_addr) < 1)
                {
                    return false;
                }

                listenfd_ = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
                if (listenfd_ == INVALID_SOCKET)
                {
                    return false;
                }

                Adjust(listenfd_);
                if (!Socket::ReuseSocketAddress(listenfd_, true))
                {
                    return false;
                }

                if (bind(listenfd_, reinterpret_cast<sockaddr*>(&in4), sizeof(in4)) < 0)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

            if (listen(listenfd_, backlog) < 0)
            {
                return false;
            }

            hEvent_ = WSACreateEvent();
            if (hEvent_ == WSA_INVALID_EVENT)
            {
                return false;
            }

            if (WSAEventSelect(listenfd_, hEvent_, FD_ACCEPT | FD_CLOSE) != NOERROR)
            {
                return false;
            }

            afo_ = make_shared_void_pointer<boost::asio::windows::object_handle>(*context_, hEvent_);
            return Next();
        }

接受套接字连入部分:

WSANETWORKEVENTS events;
if (WSAEnumNetworkEvents(listenfd, hEvent, &events) == NOERROR)
{
    if (events.lNetworkEvents & FD_ACCEPT)
    {
        if (events.iErrorCode[FD_ACCEPT_BIT] == 0)
        {
            struct sockaddr_in6 address = { 0 };
            int address_size = sizeof(address);

            int sockfd = WSAAccept(listenfd_, (sockaddr*)&address, &address_size, NULL, NULL);
            if (sockfd != INVALID_SOCKET)
            {
                AcceptSocketEventArgs e = { Adjust(sockfd) };
                OnAcceptSocket(e);
            }
        }
    }
    elif(events.lNetworkEvents & FD_CLOSE)
    {
        if (events.iErrorCode[FD_ACCEPT_BIT] == 0) /* event is operation_canceled. */
        {
            return;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/602098.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sql查询数据语句

select * from 表名 where 列名 某个数据名字 查询某个表名中的某列是否有某个数据

基于卷积神经网络的高光谱图像分类详细教程(含python代码)

目录 一、背景 二、基于卷积神经网络的代码实现 1&#xff09;建立卷积神经网络模型 2&#xff09;训练函数代码 3&#xff09;全图可视化 三、项目代码 一、背景 卷积神经网络&#xff08;Convolutional Neural Networks, CNNs&#xff09;在处理高光谱图像分类任务时&…

Mask RCNN(Mask_RCNN-master)简单部署

一.注意事项 1.本文主要是引用大佬的文章&#xff08;侵权请联系&#xff0c;马上删除&#xff09;&#xff0c;做的工作为简单补充 二.介绍 ①简介&#xff1a; Mask R-CNN&#xff08;Mask Region-based Convolutional Neural Network&#xff09;是一种用于目标检测和语义…

两个手机在一起ip地址一样吗?两个手机是不是两个ip地址

在数字时代的浩瀚海洋中&#xff0c;手机已经成为我们生活中不可或缺的一部分。随着移动互联网的飞速发展&#xff0c;IP地址成为了连接手机与互联网的桥梁。那么&#xff0c;两个手机在一起IP地址一样吗&#xff1f;两个手机是不是两个IP地址&#xff1f;本文将带您一探究竟&a…

Apipost使用心得,让接口文档变得更清晰,更快捷

Idea和Apipost结合使用 Idea 安装插件Apipost-Helper-2.0 在【file】–>【settings】–>【Plugins】搜索 “Apipost-Helper-2.0”–>【install】&#xff0c;重启Idea 编写controller接口 在idea中编写业务功能及接口之后&#xff0c;在controller中鼠标【右键】单…

亚马逊Amazon商品详情和关键词搜索API接口分享

一、亚马逊Amazon商品详情API接口 亚马逊商品详情API接口是亚马逊平台为开发者提供的一项重要服务&#xff0c;它允许开发者通过程序调用API来获取亚马逊商品的相关数据。这个接口为获取商品数据提供了便利的途径&#xff0c;有助于用户进行商品搜索、商品分类以及数据分析等操…

Stable Diffusion基础:ControlNet之人体姿势控制

在AI绘画中精确控制图片是一件比较困难的事情&#xff0c;不过随着 ControlNet 的诞生&#xff0c;这一问题得到了很大的缓解。 今天我就给大家分享一个使用Stable Diffusion WebUI OpenPose ControlNet 复制照片人物姿势的方法&#xff0c;效果可以参考上图。 OpenPose 可以…

不得不聊的微服务Gateway

一、 什么是Gateway&#xff1f; 1.网关的由来 单体应用拆分成多个服务后&#xff0c;对外需要一个统一入口&#xff0c;解耦客户端与内部服务 2.网关的作用 Spring Cloud Gateway是Spring Cloud生态系统中的一员&#xff0c;它被设计用于处理所有微服务的入口流量。作为一…

Dice Semimetric Losses: Optimizing the Dice Score with Soft Labels

文章目录 Dice Semimetric Losses: Optimizing the Dice Score with Soft Labels摘要方法实验结果 Dice Semimetric Losses: Optimizing the Dice Score with Soft Labels 摘要 Soft Dice Loss&#xff08;SDL&#xff09;在医学图像领域的许多自动分割中发挥了关键作用。在过…

【数据库原理及应用】期末复习汇总高校期末真题试卷07

试卷 一、填空题&#xff08;每空1分&#xff0c;共10分&#xff09; 1.数据库管理系统在外模式、模式和内模式这三级模式之间提供了两层映象&#xff0c;其中 映象保证了数据的逻辑独立性。 2. 数据模型通常由 、数据操作和完整性约束三部分组…

vue 文本中的\n 、<br>换行显示

一、背景&#xff1a; 后端接口返回数据以\n 作为换行符&#xff0c;前端显示时候需要换行显示&#xff1b; demo&#xff1a; <p style"white-space: pre-wrap;">{{ info }}</p>data() {return {info: 1、优化图片\n 2、 优化时间\n}},项目上&#…

通配符证书价格350元

通配符SSL证书是一种特殊的域名SSL证书&#xff0c;这款SSL证书默认保护主域名以及主域名下的所有子域名&#xff0c;因此&#xff0c;子域名比较多的个人或者企事业单位开发者都倾向于选择通配符SSL证书来简化SSL证书管理过程&#xff0c;节省购买SSL证书的资金&#xff0c;降…

前端如何设置div可滚动,且设置滚动条颜色

在前端中&#xff0c;设置 div 为可滚动并通过 CSS 自定义滚动条的颜色并不是所有浏览器都直接支持的功能&#xff0c;因为滚动条的样式在很大程度上取决于操作系统和浏览器的默认样式。然而&#xff0c;你可以使用某些 CSS 属性来尝试自定义滚动条的外观&#xff0c;这些属性在…

JavaEE概述 + Maven

文章目录 一、JavaEE 概述二、工具 --- Maven2.1 Maven功能 仓库 坐标2.2 Maven之项目构建2.3 Maven之依赖管理 三、插件 --- Maven Helper 一、JavaEE 概述 Java SE、JavaEE&#xff1a; Java SE&#xff1a;指Java标准版&#xff0c;适用于各行各业&#xff0c;主要是Java…

2024 Flutter 一季度热门 issue/roadmap 进展和个人感触闲聊

因为最近的《Flutter&#xff1a;听说你最近到处和人说我解散了&#xff1f;》相关事件之后&#xff0c;不少人对于目前 Flutter 的一些进度情况比较关心&#xff0c;刚好这里做一个简要汇总&#xff0c;报告几个过去一季度相关的热门 issue/roadmap 情况&#xff0c;另外这些天…

邮件群发系统的效率怎么样?如何评估性能?

邮件群发系统的使用方法&#xff1f;邮件群发工具的关键功能&#xff1f; 邮件群发系统已成为企业、组织及个人进行信息沟通的重要工具。然而&#xff0c;当我们谈论邮件群发系统的效率时&#xff0c;我们需要从多个维度来全面分析和评估。AokSend就来介绍一下。 邮件群发系统…

ReactFlow的ReactFlow实例事件传参undefined处理状态切换

1.问题 ReactFlow的ReactFlow实例有些事件我们在不同的状态下并不需要&#xff0c;而且有时候传参会出现其它渲染效果&#xff0c;比如只读状态下我们不想要拖拉拽onEdgesChange连线重连或删除的功能。 2.思路 事件名称类型默认值onEdgesChange(changes: EdgeChange[]) >…

AI大模型探索之路-训练篇17:大语言模型预训练-微调技术之QLoRA

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

浅谈消息队列和云存储

1970年代末&#xff0c;消息系统用于管理多主机的打印作业&#xff0c;这种削峰解耦的能力逐渐被标准化为“点对点模型”和稍复杂的“发布订阅模型”&#xff0c;实现了数据处理的分布式协同。随着时代的发展&#xff0c;Kafka&#xff0c;Amazon SQS&#xff0c;RocketMQ&…

基于大数据+Hadoop的豆瓣电子图书推荐系统实现

&#x1f339;作者主页&#xff1a;青花锁 &#x1f339;简介&#xff1a;Java领域优质创作者&#x1f3c6;、Java微服务架构公号作者&#x1f604; &#x1f339;简历模板、学习资料、面试题库、技术互助 &#x1f339;文末获取联系方式 &#x1f4dd; 系列文章目录 基于大数…
最新文章