【网络编程】使用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检查】 选择为否。

549050-20180118183944849-908616733.png

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

转载于:https://www.cnblogs.com/17bdw/p/8311763.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值