【網絡編程】使用getnameinfo()/getaddrinfo()/InetPton()
阿新 • • 發佈:2018-01-18
har addrinfo turn num instead specified com accep host
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; }
【網絡編程】使用getnameinfo()/getaddrinfo()/InetPton()