天天看點

inet_ntoa在64位機器上出錯

inet_ntoa用法如下:

char *inet_ntoa(struct in_addr in);
           

就是将struct in_addr結構轉換為IP位址的形式,struct in_addr這個結構應該不陌生吧,它的定義如下:

struct in_addr{
       unsigned long s_addr;
}
struct sockaddr_in {
       short int sin_family;
       unsigned short int sin_port; 
       struct in_addr sin_addr;
       unsigned char sin_zero[8];
};
           

在伺服器端使用accept函數之後,會得到用戶端連接配接的struct sockaddr結構,然後将其轉換成struct sockaddr_in結構,此時可以在伺服器端得到用戶端連接配接的IP和端口資料。

這時用這個函數有一個問題是:如果在64位的機器上,使用

char* tmp = inet_ntoa(sin->sin_addr);
           

之後,對tmp進行操作,會出現斷錯誤,但在32位機器上沒有問題,原因是64位時inet_ntoa傳回值是一個整型。

在網上找的兩種解決辦法:

  1. 在使用的檔案中,引用#include <arpa/inet.h>頭檔案。
  2. 直接使用inet_ntop函數。

inet_ntop的說明如下:

NAME
       inet_ntop - Parse network address structures

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>
       #include <arpa/inet.h>

       const char *inet_ntop(int af, const void *src,
                             char *dst, socklen_t cnt);

DESCRIPTION
       This  function converts the network address structure src in the af address family into a char-
       acter string, which is copied to a character buffer dst, which is cnt bytes long.

       inet_ntop(3)  extends  the  inet_ntoa(3)  function  to  support  multiple   address   families,
       inet_ntoa(3)  is  now  considered  to  be  deprecated  in favor of inet_ntop(3).  The following
       address families are currently supported:

       AF_INET
              src points to a struct in_addr (network byte order format) which is converted to an IPv4
              network address in the dotted-quad format, "ddd.ddd.ddd.ddd".  The buffer dst must be at
              least INET_ADDRSTRLEN bytes long.

       AF_INET6
              src points to a struct in6_addr (network byte order format) which is converted to a rep-
              resentation of this address in the most appropriate IPv6 network address format for this
              address.  The buffer dst must be at least INET6_ADDRSTRLEN bytes long.

RETURN VALUE
       inet_ntop() returns a non-null pointer to dst.  NULL is returned if there was  an  error,  with
       errno set to EAFNOSUPPORT if af was not set to a valid address family, or to ENOSPC if the con-
       verted address string would exceed the size of dst given by the cnt argument.

CONFORMING TO
       POSIX.1-2001.  Note that RFC 2553 defines a prototype where the last parameter cnt is  of  type
       size_t.  Many systems follow RFC 2553.  Glibc 2.0 and 2.1 have size_t, but 2.2 has socklen_t.