• 【网络编程】使用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
    ");
    			break;
    		case AF_INET:
    			printf("AF_INET (IPv4)
    ");
    			sockaddr_ipv4 = (struct sockaddr_in *) ptr->ai_addr;
    			printf("	IPv4 address %s
    ",
    				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;
    }
    
  • 相关阅读:
    Codeforces Round #443 (Div. 2)ABC
    Codeforces Round #442 (Div. 2) ABC
    Wannafly挑战赛2 Cut
    热爱工作的蒜蒜
    Codeforces Round #441 (Div. 2) (ABC)
    Codeforces Round #440 (Div. 2)(ABC)
    Codeforces Round #439 (Div. 2)(ABC)
    sphinx 分词搭建手册
    [转]Chrome 控制台console的用法
    shell脚本复制文件夹内容到另外的文件夹,如果存在则自动备份
  • 原文地址:https://www.cnblogs.com/17bdw/p/8311763.html
Copyright © 2020-2023  润新知