1. 程式人生 > >關於Socket程式設計中的inet_ntop、inet_pton和inet_ntoa、inet_addr

關於Socket程式設計中的inet_ntop、inet_pton和inet_ntoa、inet_addr

VS2013中除錯Socket程式碼時,遇到了點小問題:

問題程式碼為:

  1. inet_ntoa(addrClient.sin_addr);  

生成錯誤訊息為:

  1. error C4996: 'inet_ntoa': Use inet_ntop() or InetNtop() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings  
  2. 1>          c:\program files (x86)\windows kits\8.1\include\um\winsock2.h(1868) : 參見“inet_ntoa”的宣告  

看到這條訊息就有點懵了,之前在VS2010中好好的,怎麼在這裡就不行了。

然後試著:

1. 把SDL檢查關閉,發現可以通過,但是error變成了warning。先說一下SDL關閉:在“專案”-“屬性”-“配置屬性”-“C/C++”-“常規”下,有一項“SDL檢查”,把“是 (/sdl)”改為“否(/sdl-)”就可以了。

2. 加上語句: #pragma comment(lib, "ws2_32.lib")

SDL安全檢查在VS2010中是沒有的,從VS2012開始就有了。inet_pton和inet_ntop這2個IP地址轉換函式,能夠處理ipv4和ipv6,算是比較新的函數了,可以在將IP地址在“點分十進位制”和“二進位制整數”之間轉換。SDL提示錯誤可能是推薦使用相對安全的函式吧。那麼,關閉了SDL確實可以了,但warning還在啊,所以找個更好的辦法。

首先根據提示看看“inet_ntoa”的宣告,在標頭檔案WinSock2.h中:

  1. char FAR *  
  2. WSAAPI  
  3. inet_ntoa(  
  4.     _In_ struct in_addr in  
  5. );  

Inet_ntoa的引數是一個in_addr的結構體。這個結構體將一個點分十進位制格式的IP地址轉換為u_long型別,儲存在S_addr中。

再看看inet_ntop的定義,在檔案WS2tcpip.h中:

  1. PCSTR  
  2. WSAAPI  
  3. inet_ntop(  
  4.     _In_                                INT             Family,  
  5.     _In_                                PVOID           pAddr,  
  6.     _Out_writes_(StringBufSize)         PSTR            pStringBuf,  
  7.     _In_                                size_t          StringBufSize  
  8. );  
第一個引數(Family)指定地址族,對於TCP/IP協議的套接字,地址族為AF_INET;第二個引數(pAddr)指向套接字的IP地址(sin_addr);第三個引數(pStringBuf)是字串緩衝區;第四個引數(StringBufSize)指定緩衝區的大小,這裡值為16,用來儲存點分十進位制格式的IP地址。

那麼,修改後的程式碼為:

  1. // char sendBuf[100];  
  2. // SOCKADDR_IN addrClient;  
  3. inet_ntop(AF_INET, (void*)&addrClient.sin_addr, sendBuf, 16);  
再次編譯就沒有警告了。注:inet_ntop函式成功的話返回字串的首地址,錯誤返回NULL。 inet_pton功能與inet_ntop正好相反,將“點分十進位制” 轉換為 “二進位制整數”。
  1. INT  
  2. WSAAPI  
  3. inet_pton(  
  4.     _In_                                      INT             Family,  
  5.     _In_                                      PCSTR           pszAddrString,  
  6.     _Out_writes_bytes_(sizeof(IN6_ADDR))      PVOID           pAddrBuf  
  7.     );  
注:inet_pton函式成功的話返回1,引數無效返回0,錯誤返回-1。