支持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在很多架构和考虑上面不能满足现代化的 ...
随机推荐
- _3_body_标签
创:20_3_2017修:5_4_2017 什么是div标签? div 双 -- div标签没有任何默认属性 -可以任意写入样式和内容,和 水一样,水自然平凡而又最多 什么是h1标签? h1 标题(双 ...
- springmvc图片上传(兼容ie8以上,实时预览)
html代码: <form id="uploadform" method="post" enctype="multipart/form-data ...
- chroot: failed to run command `/bin/bash': No such file or directory
1 使用chroot命令时报错如下: testupgrade:/ # chroot /sb chroot: cannot change root directory to /sb: No such f ...
- 【Python3之迭代器,生成器】
一.可迭代对象和迭代器 1.迭代的概念 上一次输出的结果为下一次输入的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值 注:循环不是迭代 while True: ...
- Calendar使用方法
Calendar类的静态方法getInstance()可以初始化一个日历对象: Calendar now = Calendar.getInstance(); 可以使用下面三个方法把日历定到任何一个时间 ...
- MongoDB 基本操作学习笔记
// 查看所有数据库 show dbs // amdin 0.000GB // local 0.000GB // 使用数据库 use admin // switched to db admin // ...
- ftp服务配置
文件传输协议(File Transfer Protocol,FTP),基于该协议FTP客户端与服务端可以实现共享文件.上传文件.下载文件. FTP 基于TCP协议生成一个虚拟的连接,主要用于控制F ...
- chrome disable-web-security 关闭安全策略 解决跨域
Chrome 跨域访问线上接口 时间:2016-04-21 作者:zhongxia 前后端分离之后,联调的时候就会出现问题,那就是Ajax跨域问题. 跨域问题的解决方案有很多种比如常规的 后端使用CR ...
- 我的前端故事----关于前端数据&逻辑的思考
最近重构了一个项目,一个基于redux模型的react-native项目,目标是在混乱的代码中梳理出一个清晰的结构来,为了实现这个目标,首先需要对项目的结构做分层处理,将各个逻辑分离出来,这里我是基于 ...
- Installing VirtualBox
The (VirtualBox) website has a lot of quality documentation including: End-user documentation Techni ...