支持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在很多架构和考虑上面不能满足现代化的 ...
随机推荐
- Windows任务计划程序起始于参数自动修改
Windows任务计划程序建立后,手工运行可以成功,但计划任务自动运行却不能成功,搜索网络,原来是起始于参数没有配置,这个参数的英文名字是start-in.它保证任务计划程序的WorkingDirec ...
- Universe Design Tool Using JDBC connect Sybase/Oracle Get Error
一.针对Sybase 1 使用SAP Universe 设计工具连接Sybase数据库报错,报错如下: “CS: Java Class not found in classpath : com.syb ...
- query返回值
总结:PDO::query($sql)返回值是一个对象,其中包括了你输入的sql语句 而fetch()方法执行成功则返回包含一条记录的数组,失败返回false. $rs = $pdo -> ...
- JavaScript数据结构 (手打代码)
array: 数组创建: ); //创建一个长度为6的数组 ,,,,,); 数组方法: var str="I love javascript"; var single=str.sp ...
- FastDFS分布式存储实战
<FastDFS分布式存储实战> 技术选型 FastDFS相关组件及原理 FastDFS介绍 FastDFS架构 FastDFS工作流程 上传 同步机制 下载 文件合并原理 实验环境说明 ...
- 6 个 Linux 运维典型问题
作为一名合格的 Linux 运维工程师,一定要有一套清晰.明确的解决故障思路,当问题出现时,才能迅速定位.解决问题,这里给出一个处理问题的一般思路: 重视报错提示信息:每个错误的出现,都是给出错误提示 ...
- KVM详情
KVM介绍 Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux 2.6.20之后集成在Linux的各个主要发行版本中.它使用Linux自身的调度器 ...
- lvs+keepalive构建高可用集群
大纲 一.前言 二.Keepalived 详解 三.环境准备 四.LVS+Keepalived 实现高可用的前端负载均衡器 一.前言 Keepalived使用的vrrp协议方式,虚拟路由 ...
- JAVA并发编程学习笔记------FutureTask
FutureTask是Future和Callable的结合体.传统的代码是这样写的Future f = executor.submit(new Callable()); 然后通过Future来取得计算 ...
- Hello 2018
愈发觉得写技术博客对于自己写作能力的提升会很有帮助,于是在今天终于用Github+Jekyll的方式搭建了自己的博客,从今往后就在这里记录自己在技术上成长的点滴,希望自己的总结和思考也能帮助到其他人. ...