报错:error C4996: ‘inet_addr’: Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
inet_pton是一个IP地址转换函数,可以在将IP地址在“点分十进制”和“二进制整数”之间转换而且,inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。算是比较新的函数了。
头文件:
windows下:
#include <WS2tcpip.h>
linux下:
#include <sys/socket.h>
#include <netinet/in.h>
#include<arpa/inet.h>
函数原型:
inet_pton:将“点分十进制” -> “二进制整数”
int inet_pton(int af, const char *src, void *dst);
这个函数转换字符串到网络地址,第一个参数af是地址簇,第二个参数*src是来源地址,第三个参数* dst接收转换后的数据。
inet_pton 是inet_addr的扩展,支持的多地址族有下列:
af = AF_INET
src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址转换为in_addr的结构体,并复制在*dst中。
af = AF_INET6
src为指向IPV6的地址,函数将该地址转换为in6_addr的结构体,并复制在*dst中。
如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。
// win64-tcp-server.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#if defined(_WIN64) || defined(WIN32)
#include <WinSock2.h> //must be here!!!
// #include <IPHlpApi.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib") //add ws2_32.lib
#else
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <string.h>
using namespace std;
#include <stdlib.h>
#include <iostream>
#include <string>
//
//
int main(int argc, char *argv[])
{
if (argc != 3)
{
printf("usage: argc(%u) != 3\n", argc);
return -1;
}
WORD wVersionRequested;
WSADATA wsaData;
int err, iLen;
wVersionRequested = MAKEWORD(2, 2);//create 16bit data
//(1)Load WinSock
err = WSAStartup(wVersionRequested, &wsaData); //load win socket
if (err != 0)
{
printf("Load WinSock Failed!\n");
return -1;
}
SOCKET m_nSocket = ::socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_nSocket == INVALID_SOCKET)
{
int err = WSAGetLastError();
printf("::socket() create is failed. err=[%d]\n", err);
return -1;
}
// 设置SOCKET为KEEPALIVE
int optval = 1;
if (setsockopt(m_nSocket, SOL_SOCKET, SO_KEEPALIVE, (char *)&optval, sizeof(optval)))
{
int err = WSAGetLastError();
printf("setsockopt set SO_KEEPALIVE failed. err=[%d]\n", err);
::closesocket(m_nSocket);
return -1;
}
//设置成非阻塞模式
unsigned long ulBlocking = 1;
int ret = ioctlsocket(m_nSocket, FIONBIO, (unsigned long *)&ulBlocking);
if (ret == SOCKET_ERROR)
{
int err = WSAGetLastError();
printf("setsockopt set FIONBIO failed. err=[%d]\n", err);
::closesocket(m_nSocket);
return -1;
}
// 设置地址重用
unsigned long ulReuse = 1;
ret = setsockopt(m_nSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&ulReuse, sizeof(ulReuse));
if (ret == SOCKET_ERROR)
{
int err = WSAGetLastError();
printf("setsockopt set SO_REUSEADDR failed. err=[%d]\n", err);
::closesocket(m_nSocket);
return -1;
}
char *pEnd = NULL;
int usPort = atoi(argv[2]);
if (usPort == 0)
{
printf("fail to parse port: %u\n", usPort);
return -1;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_family = AF_INET;
inet_pton(AF_INET, argv[1], (void*)&addrSrv.sin_addr.s_addr);//htonl(INADDR_ANY);//Auto IP, byte sequence change
addrSrv.sin_port = htons(usPort);
ret = ::bind(m_nSocket, (SOCKADDR*)&addrSrv, sizeof(addrSrv));
if (SOCKET_ERROR == ret)
{
int err = WSAGetLastError();
printf("bind is failed. err=[%d]\n", err);
return false;
}
//(5)listen
err = listen(m_nSocket, 5);
if (err != 0)
{
printf("listen is fai=[%u]\n", WSAGetLastError());
return -4;
}
cout << "Server waitting...:" << endl;
//(6)client ip
SOCKADDR_IN addrClt;
int len = sizeof(SOCKADDR);
while (1)
{
//(7)accept
SOCKET sockConn = accept(m_nSocket, (SOCKADDR*)&addrClt, &len);
if (sockConn - 1)
{
cout << "wait for accept" << endl;
Sleep(1000);
continue;
}
char sendBuf[1024] = {0};
string strmsg("abcdefghijklmnopqrst");
memcpy(sendBuf, strmsg.data(), strmsg.size());
//(8)send recv
err = send(sockConn, sendBuf, strlen(sendBuf) + 1, 0);
char recvBuf[1024] = "\0";
iLen = recv(sockConn, recvBuf, 1024, 0);
recvBuf[iLen] = '\0';
cout << recvBuf << endl;
//(9)close connected sock
closesocket(sockConn);
}
//(10)close server sock
closesocket(m_nSocket);
//(11)clean up winsock
WSACleanup();
return 0;
}