支持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在很多架构和考虑上面不能满足现代化的 ...
随机推荐
- 微信跳一跳的mini辅助设计
前一段考试没时间写东西,就迟到补发一波,继电器触发触屏,arduino处理数据就行了,B站很多人做,我也来一个,个人测试数据增益为2.1左右,即 延时=距离X2.1x10 void setup() ...
- python_计算1+……+100中偶数和
如何计算1+--+100中偶数和? 1. 把奇数去掉,通过if,判断累加数除以2的余数,是否为1,判断是否是奇数 2. 通过continue 跳过对奇数的累加 #!/usr/bin/python3 d ...
- java IO(三):字符流
*/ .hljs { display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; } .hl ...
- js中的监听事件总结
javascript事件与功能说明大全:http://tools.jb51.net/table/javascript_event 1.滚动条监听事件 例1:监听滚动条距离页面顶端距离 <scri ...
- 【转】 linux下的awk程序执行
#!/bin/awk -f awk脚本开头使用这个命令,赋予这个文本文件以执行的权限.这样做之后,你就可以在命令行中用类似于下面这样的方式调用并执行这段awk程序了. BEGIN和END的大括号必须紧 ...
- 【php】RBAC 管理权限
用户 角色 权限 用户:张三 角色:管理员 权限:page/index1.php 能访问的页面
- 2017noip普及组赛前注意事项总结
petr 大神镇场 距人生第一场noip只差4天半了(好紧张) 总结几下四道题的做题策略 NO1 第一题一般是送分的,认真读题,别太草率,多想几遍再动手,把重要的地方圈一圈.画一画,自己找几个数据多试 ...
- 老凡原创PHPcms发布上架chinaz
FanCms内容管理系统(3网兼容) FanCms内容管理系统(3网兼容)核心使用CodeIgniter框架.使用SQlite数据库,不需要安装,上传到任意支持PHP的空间,就能使用.高级URL自定义 ...
- ansible playbook实践(二)-基础相关命令
ansible相关的命令: ansible 用来执行ansible管理命令 ansible-doc 用来获取模块的帮助文档 ansible-playbook 当有众多任务时,可编写成playbook ...
- 在eclipse的配置文件里指定jdk路径
在eclipse的配置文件里指定jdk路径,只需在eclipse的配置文件里增加-vm参数即可. 打开eclipse目录下的eclipse.ini配置文件,增加-vm配置,需要注意的是该参数要加在-v ...