您的位置:首页 > 编程语言

支持ipV6和ipV4的客户端编程

2018-01-13 17:21 323 查看
ipv4和ipv6在socket初始化的时候是不一样的。

ipv4 socket初始化:

int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd; //WSADATA变量
SOCKADDR_IN servAddr; //服务器地址
int retVal; //返回值
int nServAddlen;

//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
return -1;
}

sprintf_s(m_szIP, sizeof(m_szIP), strIP);

memset(&servAddr, 0, sizeof(servAddr));

//创建套接字
m_sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
WSACleanup();//释放套接字资源
return  -1;
}

//设置服务器地址
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);
if (SOCKET_ERROR == retVal)
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}
return 0;
}


ipv6 socket初始化:

int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd; //WSADATA变量
struct sockaddr_in6 servAddr_in6; //服务器地址
int retVal; //返回值
int nServAddlen;

//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
return -1;
}

sprintf_s(m_szIP, sizeof(m_szIP), strIP);

memset(&servAddr_in6, 0, sizeof(struct sockaddr_in6));

//创建套接字
m_sHost = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == m_sHost)
{
return  -1;
}

//设置服务器地址
servAddr_in6.sin6_family = AF_INET6;

if (!inet_pton(AF_INET6, m_szIP, &servAddr_in6.sin6_addr.s6_addr))
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return  -1;
}
servAddr_in6.sin6_port = htons(portNum);
nServAddlen = sizeof(servAddr_in6);
//连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr_in6, (socklen_t)nServAddlen);

if (SOCKET_ERROR == retVal)
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}

//退出
return 0;
}


将上面的逻辑合二为一:

int CClient::InitSocket(CString strIP, short portNum)
{
WSADATA wsd; //WSADATA变量
struct sockaddr_in6 servAddr_in6; //服务器地址
SOCKADDR_IN servAddr; //服务器地址
int retVal; //返回值
int nServAddlen;

//初始化套结字动态库
if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{
return -1;
}

sprintf_s(m_szIP, sizeof(m_szIP), strIP);

memset(&servAddr, 0, sizeof(servAddr));
memset(&servAddr_in6, 0, sizeof(struct sockaddr_in6));

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  -1;
}

//设置服务器地址
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  -1;
}

//设置服务器地址
servAddr_in6.sin6_family = AF_INET6;

if (!inet_pton(AF_INET6, m_szIP, &servAddr_in6.sin6_addr.s6_addr))
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return  -1;
}
servAddr_in6.sin6_port = htons(portNum);
nServAddlen = sizeof(servAddr_in6);
//连接服务器
retVal = connect(m_sHost, (LPSOCKADDR)&servAddr_in6, (socklen_t)nServAddlen);
}

if (SOCKET_ERROR == retVal)
{
closesocket(m_sHost); //关闭套接字
WSACleanup(); //释放套接字资源
return -1;
}

//退出
return 0;
}


判断一个ip是不是ipv4的

/*判断传入的字符串是否为ipv4格式的
*/
bool CClient::is_string_ipaddr_ipv4(const char* str_ipv4, struct in_addr *ip)
{
int32 ret = -1;
struct in_addr tmp_ip;

memset(&tmp_ip, 0, sizeof(struct in_addr));

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

if (0 == *str_ipv4)
{
return false;
}

ret = inet_pton(AF_INET, str_ipv4, &tmp_ip);
if (0 == ret)
{
return false;
}
else if (ret < 0)
{
return false;
}
else
{
if (NULL != ip)
{
memcpy(ip, (void *)&tmp_ip, sizeof(struct in_addr));
}

return true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: