【网络编程】使用getnameinfo()/getaddrinfo()/InetPton()

1、简要

从前用的网络编程函数现在又做了一定的改动,报了这么3个错误。

error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings

error C4996: 'gethostbyaddr': Use getnameinfo() or GetNameInfoW() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings

error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings

2、解决方法1

右键属性-属性页选择【C/C++】->【常规】->【SDL检查】 选择为否。

3、代码解决

既然已经明确提示需要换更安全的函数,那就按照要求来就好了。

serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//自己的IP或者127.0.0.1

改为:

//新改进代码
InetPton(AF_INET, _T("127.0.0.1"), &serverAddr.sin_addr.s_addr);

gethostbyaddr()改用getnameinfo();

inet_ntop()改用getaddrinfo();

修改后的代码:

#include "stdafx.h"
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
#include <Ws2tcpip.h>

/*
1. 初始化环境        wsastartup
2. 创建套接字        socket
3. 绑定套接字        bind
4. 监听套接字        listen
5. 处理套接字连接      accept
6. 发送接收数据       send/recv
7. 关闭套接字        closesocket
8. 清理环境         wsacleanup
*/
int main()
{
	// 1. 初始化环境     wsastartup
	WSADATA wsd = { 0 };
	int re = WSAStartup(MAKEWORD(2, 2), &wsd);
	if (re != 0) { return 0; }
	if (LOBYTE(wsd.wVersion) != 2 ||
		HIBYTE(wsd.wVersion) != 2)
	{
		return 0;
	}
	// 2. 创建套接字     socket
	SOCKET listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (listenSock == INVALID_SOCKET)
	{
		return 0;
	}
	// 3. 绑定套接字     bind
	sockaddr_in serverAddr;
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(0x5566);
        //旧代码
	//serverAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//自己的IP或者127.0.0.1

	//新改进代码
	InetPton(AF_INET, _T("127.0.0.1"), &serverAddr.sin_addr.s_addr);

	re = bind(listenSock, (sockaddr *)&serverAddr, sizeof(serverAddr));

	// 4. 监听套接字     listen
	re = listen(listenSock, SOMAXCONN);

	// 5. 处理套接字连接   accept
	sockaddr_in clientAddr;
	int size = sizeof(clientAddr);
	SOCKET sToClientSock = accept(
		listenSock, (sockaddr *)&clientAddr, &size);

	//测试获取的结果
	//更换为新函数查看使用结果
	//旧 主机名
	hostent * pHost = gethostbyaddr((char *)&serverAddr.sin_addr, 4, AF_INET);
	//旧  IP地址
	char * p = inet_ntoa(*(struct in_addr *) (*pHost->h_addr_list));
	

	//新代码测试
	///////////////////////////////////////////////////////////////////
	struct addrinfo *ptr = NULL;
	struct addrinfo hints;
	struct addrinfo *result = NULL;
	struct sockaddr_in  *sockaddr_ipv4;

	char hostname[NI_MAXHOST]; //主机名称
	char servInfo[NI_MAXSERV]; //具体连接成功的端口

	getnameinfo((struct sockaddr *) &serverAddr,
		sizeof(struct sockaddr),
		hostname,
		NI_MAXHOST, servInfo, NI_MAXSERV, NI_NUMERICSERV);

	ZeroMemory(&hints, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	getaddrinfo(hostname, servInfo, &hints, &result);
	for (ptr = result; ptr != NULL; ptr = ptr->ai_next) {
	
		switch (ptr->ai_family) {
		case AF_UNSPEC:
			printf("Unspecified\n");
			break;
		case AF_INET:
			printf("AF_INET (IPv4)\n");
			sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
			printf("\tIPv4 address %s\n",
				inet_ntoa(sockaddr_ipv4->sin_addr));
			break;
		}
	
	}
	///////////////////////////////////////////////////////////////////



	// 6.1 发送数据 send
	char buf[100] = "hello socket client,from server!";
	re = send(sToClientSock, buf, strlen(buf), 0);
	if (re == SOCKET_ERROR)
	{
		goto over;
	}
	// 6.2 接收数据  recv
	re = recv(sToClientSock, buf, sizeof(buf), 0);
	if (re == INVALID_SOCKET)
	{
		goto over;
	}
over:
	// 7. 关闭套接字     closesocket
	closesocket(listenSock);
	closesocket(sToClientSock);
	// 8. 清理环境      wsacleanup
	WSACleanup();

	return 0;
}
posted @ 2018-01-18 18:45  17bdw  阅读(962)  评论(0编辑  收藏  举报