支持ipV6和ipV4的客户端编程
ipv4和ipv6在socket初始化的时候是不一样的。
ipv4 socket初始化:
int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd;
SOCKADDR_IN servAddr;
int retVal;
//初始化套结字动态库
if (WSAStartup(MAKEWORD(, ), &wsd) != )
{
return -;
}
//创建套接字
m_sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
WSACleanup();//释放套接字资源
return -;
} //设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr((LPCTSTR)strIP);
servAddr.sin_port = htons(portNum);
int nServAddlen = sizeof(servAddr); //设置非阻塞方式连接
unsigned long ul = ;
retVal = ioctlsocket(m_sHost, FIONBIO, (unsigned long*)&ul);
if (retVal == SOCKET_ERROR) return ; //连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)); if (retVal == )
{ }
else
{
int iErr = GetLastError();
if (WSAEWOULDBLOCK == iErr)
{
struct timeval timeout;
fd_set r; FD_ZERO(&r);
FD_SET(m_sHost, &r);
timeout.tv_sec = ;
timeout.tv_usec = ;
retVal = select(m_sHost + , NULL, &r, NULL, &timeout);
if (retVal <= )
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -;
}
}
} //退出
return ;
}
ipv6 socket初始化:
int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd;
struct sockaddr_in6 servAddr_in6;
int retVal;
int nServAddlen; //初始化套结字动态库
if (WSAStartup(MAKEWORD(, ), &wsd) != )
{
return -;
} sprintf_s(m_szIP, sizeof(m_szIP), strIP); memset(&servAddr_in6, , sizeof(struct sockaddr_in6)); //创建套接字
m_sHost = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
return -;
} //设置服务器地址
servAddr_in6.sin6_family = AF_INET6; if (!inet_pton(AF_INET6, m_szIP, &servAddr_in6.sin6_addr.s6_addr))
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -;
} //设置非阻塞方式连接
unsigned long ul = ;
retVal = ioctlsocket(m_sHost, FIONBIO, (unsigned long*)&ul);
if (retVal == SOCKET_ERROR) return ; servAddr_in6.sin6_port = htons(portNum);
nServAddlen = sizeof(servAddr_in6);
//连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr_in6, (socklen_t)nServAddlen); if (retVal == )
{ }
else
{
int iErr = GetLastError();
if (WSAEWOULDBLOCK == iErr)
{
struct timeval timeout;
fd_set r; FD_ZERO(&r);
FD_SET(m_sHost, &r);
timeout.tv_sec = ;
timeout.tv_usec = ;
retVal = select(m_sHost + , NULL, &r, NULL, &timeout);
if (retVal <= )
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -;
}
}
} //退出
return ;
}
将上面的逻辑合二为一:
int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd;
struct sockaddr_in6 servAddr_in6;
SOCKADDR_IN servAddr;
int retVal;
int nServAddlen; //初始化套结字动态库
if (WSAStartup(MAKEWORD(, ), &wsd) != )
{
return -;
} sprintf_s(m_szIP, sizeof(m_szIP), strIP); memset(&servAddr, , sizeof(servAddr));
memset(&servAddr_in6, , sizeof(struct sockaddr_in6)); //设置非阻塞方式连接
unsigned long ul = ;
retVal = ioctlsocket(m_sHost, FIONBIO, (unsigned long*)&ul);
if (retVal == SOCKET_ERROR) return ;
if (TRUE == is_string_ipaddr_ipv4(m_szIP, &servAddr.sin_addr))
{
//创建套接字
m_sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
WSACleanup();//释放套接字资源
return -;
} //设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(m_szIP);
servAddr.sin_port = htons(portNum);
nServAddlen = sizeof(servAddr);
//连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr, (socklen_t)nServAddlen);
}
else
{
//创建套接字
m_sHost = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
return -;
} //设置服务器地址
servAddr_in6.sin6_family = AF_INET6; if (!inet_pton(AF_INET6, m_szIP, &servAddr_in6.sin6_addr.s6_addr))
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -;
}
servAddr_in6.sin6_port = htons(portNum);
nServAddlen = sizeof(servAddr_in6);
//连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr_in6, (socklen_t)nServAddlen);
} if (retVal == )
{ }
else
{
int iErr = GetLastError();
if (WSAEWOULDBLOCK == iErr)
{
struct timeval timeout;
fd_set r; FD_ZERO(&r);
FD_SET(m_sHost, &r);
timeout.tv_sec = ;
timeout.tv_usec = ;
retVal = select(m_sHost + , NULL, &r, NULL, &timeout);
if (retVal <= )
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -;
}
}
} //退出
return ;
}
判断一个ip是不是ipv4的
/*判断传入的字符串是否为ipv4格式的
*/
bool CClient::is_string_ipaddr_ipv4(const char* str_ipv4, struct in_addr *ip)
{
int32 ret = -;
struct in_addr tmp_ip; memset(&tmp_ip, , sizeof(struct in_addr)); if (NULL == str_ipv4)
{
return false;
} if ( == *str_ipv4)
{
return false;
} ret = inet_pton(AF_INET, str_ipv4, &tmp_ip);
if ( == ret)
{
return false;
}
else if (ret < )
{
return false;
}
else
{
if (NULL != ip)
{
memcpy(ip, (void *)&tmp_ip, sizeof(struct in_addr));
} return true;
}
}
支持ipV6和ipV4的客户端编程的更多相关文章
- keepalive配置支持ipv6、ipv4双棧支持
因公司业务需要,keepalived需要同时支持ipv6和ipv4 keepalived版本1.2.23. keepalived 配置: 重点:ipv6的虚IP配置在 virtual_ipaddres ...
- iOS应用支持IPV6,就那点事儿
原文连接 果然是苹果打个哈欠,iOS行业内就得起一次风暴呀.自从5月初Apple明文规定所有开发者在6月1号以后提交新版本需要支持IPV6-Only的网络,大家便开始热火朝天的研究如何支持IPV6 ...
- iOS应用支持IPV6
一.IPV6-Only支持是啥? 首先IPV6,是对IPV4地址空间的扩充.目前当我们用iOS设备连接上Wifi.4G.3G等网络时,设备被分配的地址均是IPV4地址,但是随着运营商和企业逐渐部署IP ...
- OSS支持IPV6/IPV4双栈访问域名
摘要: OSS开放IPv6/IPv4双栈域名,可同时支持IPv6/IPv4客户端的访问,支持下一代互联网技术IPv6,可服务海量物理网设备连接等应用场景. 下一代IP协议 IPv4地址已接近枯竭,被誉 ...
- iOS 支持 IPv6
苹果的规定:2016年6月1日提交到App Store必须支持IPv6-only网络. 官方文档:https://developer.apple.com/library/mac/documentati ...
- PPTP支持IPv6
pptp支持ipv6,谷歌资料不多,这里整理下 主要用来给ipv4访问ipv6资源的场景使用,客户端连接上pptp后会分配得到一个ipv6地址,通过此地址访问ipv6的资源 客户端网段在pptp. ...
- HP-Socket v5.0.1:支持 IPv6 及多 SSL 证书
HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...
- 配置阿里云ECS支持IPv6,解决苹果app审核失败问题
前几天iOS的App提交给苹果审核没通过,给出的原因是:该应用在 IPv6 的环境下无法使用.检查发现:阿里云优化过的系统没有启用IPv6协议,需要配置启用一下,但是只单独启用IPv6也是无法直接提供 ...
- 成功扩展live555支持ipv6,同时支持RTSPServer & RTSPClient
live555对ipv6的扩展 从live555的官网看live555的发展历史,实在是历史悠久,保守估计已经发展了至少16年以上了,同时,这也导致了live555在很多架构和考虑上面不能满足现代化的 ...
随机推荐
- 我的Android手册
目录解释说明 assets文件说明 app_id:机智云 app id app_secret:机智云 app secret product_key:机智云 product key wifi_type_ ...
- python3 第二十二章 - 函数式编程之Decorator(装饰器)
前面我们说了,在python中,一切皆对象.函数也是一个对象,而且函数对象可以被赋值给变量,通过变量也能调用该函数.如: def sayHello(name): print(name + ' hell ...
- linux_samba服务安装
什么是samba服务? 用于Windows和linux系统之间实现共享文件的目的服务 如何配置其服务? Linux端: 搭建服务 1. 安装samba yum install -y samba 2. ...
- python 爬取B站视频弹幕信息
获取B站视频弹幕,相对来说很简单,需要用到的知识点有requests.re两个库.requests用来获得网页信息,re正则匹配获取你需要的信息,当然还有其他的方法,例如Xpath.进入你所观看的视频 ...
- C语言学习之递归
学习C语言到递归时,还记得那个用来抛砖引玉的例子: "从前呀,有座山,山里有个老和尚给一个小和尚讲故事,讲的什么故事呢?从前呀,有座山,山里有个老和尚给一个小和尚讲故事,讲的什么故事呢?从前 ...
- 二目运算符 “->”
-> 在C语言中称为间接引用运算符,是二目运算符,优先级同成员运算符“.”.用法:p->a,其中p是指向一个结构体的指针,a是这个结构体类型的一个成员.表达式p->a引用了指针p指向 ...
- 我的前端故事----关于前端数据&逻辑的思考
最近重构了一个项目,一个基于redux模型的react-native项目,目标是在混乱的代码中梳理出一个清晰的结构来,为了实现这个目标,首先需要对项目的结构做分层处理,将各个逻辑分离出来,这里我是基于 ...
- 多线程访问DataTable
项目中需要读取数据库中的多张表.由于表的数据比较多,串行读取时耗时比较多,所以对程序做了一点优化. 环境 .NET 3.5,SQL Server 2012,Visual Studio 2015 过程 ...
- Django(三) ORM操作
一.DjangoORM 创建基本类型及生成数据库表结构 1.简介 ORM:关系对象映射.定义一个类自动生成数据库的表结构. 数据库常用的数据类型 : 数字 字符串 时间 ORM分为两种类型: 主流都是 ...
- 洛谷 [P2774] 方格取数问题
二分图最大点权独立集 通过题目描述我们可以很明显的看出要通过二分图建模,二分图求最大独立点集很容易,就是建立二分图求n-最小割,然而这里加入了权值,而且权值是在点上的,那么我们对于每个点连一条到源点或 ...