zoukankan      html  css  js  c++  java
  • socket编程头文件分析

    在socket网络编程中经常用到一些宏定义、结构和函数,这些经常包含在相关的头文件中,使用时直接include相关头文件即可。下面简单描述下相关的一些结构及头文件。

    1. sockaddr  / bits/socket.h

    socket编程最基本的就是socket地址,其定义在bits/socket.h中。但sys/socket.h包含bits/socket.h,且bits/socket.h明确指出该头文件不能直接使用,应使用sys/socket.h代替。

    struct sockaddr
      {
        __SOCKADDR_COMMON (sa_);    /* Common data: address family and length.  */
        char sa_data[14];       /* Address data.  */
      };

    其中__SOCKADDR_COMMON()宏定义在bits/sockaddr.h中

    #define __SOCKADDR_COMMON(sa_prefix) 
      sa_family_t sa_prefix##family
    
    #define __SOCKADDR_COMMON_SIZE  (sizeof (unsigned short int))

    替换后为

    struct sockaddr{
        unsigned short sa_family;
        char sa_data[14];
    };

    在bits/socket.h中还定义了协议族(Protocol families,PF_xxx)和地址族(Address families,AF_xx),两者一一对应,因此可以互换,应用场合根据概念稍有不同。

    #define PF_UNSPEC   0   /* Unspecified.  */
    #define PF_LOCAL    1   /* Local to host (pipes and file-domain).  */
    #define PF_UNIX     PF_LOCAL /* POSIX name for PF_LOCAL.  */
    #define PF_FILE     PF_LOCAL /* Another non-standard name for PF_LOCAL.  */
    #define PF_INET     2   /* IP protocol family.  */
    #define PF_AX25     3   /* Amateur Radio AX.25.  */
    #define PF_IPX      4   /* Novell Internet Protocol.  */
    #define PF_APPLETALK    5   /* Appletalk DDP.  */
    
    #define PF_INET6    10  /* IP version 6.  */
    
    #define PF_LLC      26  /* Linux LLC.  */
    #define PF_CAN      29  /* Controller Area Network.  */
    
    #define PF_NFC      39  /* NFC sockets.  */
    #define PF_VSOCK    40  /* vSockets.  */
    #define PF_MAX      41  /* For now..  */

    2. sys/socket.h

    该头文件包含常用的socket编程函数接口,如:

    socket() bind() listen() connect() accept() shutdown()

    send() recv() sendto() recvfrom() sendmsg() recvmsg() sendmmsg() recvmmsg()

    socketpair() getsockname() getpeername()

    getsockopt() setsockopt()

    除此外,sys/socket.h包含bits/socket.h,需要bits/socket.h的函数直接include sys/socket.h即可。

    3. 网络socket地址 sockaddr_in -- netinet/in.h

    与internet网络相关的头文件大部分在netinet目录下,如in.h ip.h(ip协议相关数据结构) tcp.h(tcp协议) udp.h(udp协议) ip_icmp.h(icmp协议) ip6.h icmp6.h等。

    在网络编程中用到的socket地址是经过转换的网络socket地址sockaddr_in:

    /* Structure describing an Internet socket address.  */
    struct sockaddr_in
      {
        __SOCKADDR_COMMON (sin_);    /* unsigned short sin_family; */
        in_port_t sin_port;         /* Port number.  */
        struct in_addr sin_addr;        /* Internet address.  */
    
        /* Pad to size of `struct sockaddr'.  */
        unsigned char sin_zero[sizeof (struct sockaddr) -
                   __SOCKADDR_COMMON_SIZE -
                   sizeof (in_port_t) -
                   sizeof (struct in_addr)];
      };

    网络地址

    /* Internet address.  */
    typedef uint32_t in_addr_t;
    struct in_addr
      {
        in_addr_t s_addr;
      };  

    网络端口

    /* Type to represent a port.  */
    typedef uint16_t in_port_t;

    据此也可推断出:唯一确定一个连接(socket)的五要素:目的IP,目的端口,源IP,源端口,协议。

    经典的4个主机网络字节序转换函数

    /* Functions to convert between host and network byte order.
    
       Please note that these functions normally take `unsigned long int' or
       `unsigned short int' values as arguments and also return them.  But
       this was a short-sighted decision since on different systems the types
       may have different representations but the values are always the same.  */
    
    extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
    extern uint16_t ntohs (uint16_t __netshort)
         __THROW __attribute__ ((__const__));
    extern uint32_t htonl (uint32_t __hostlong)
         __THROW __attribute__ ((__const__));
    extern uint16_t htons (uint16_t __hostshort)
         __THROW __attribute__ ((__const__));

    netinet/in.h定义了标准协议enum:

    enum
      {
        IPPROTO_IP = 0,    /* Dummy protocol for TCP.  */
    #define IPPROTO_IP      IPPROTO_IP
        IPPROTO_ICMP = 1,      /* Internet Control Message Protocol.  */
    #define IPPROTO_ICMP        IPPROTO_ICMP
        IPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */
    #define IPPROTO_IGMP        IPPROTO_IGMP
        IPPROTO_IPIP = 4,      /* IPIP tunnels (older KA9Q tunnels use 94).  */
    #define IPPROTO_IPIP        IPPROTO_IPIP
        IPPROTO_TCP = 6,       /* Transmission Control Protocol.  */
    #define IPPROTO_TCP     IPPROTO_TCP
        IPPROTO_EGP = 8,       /* Exterior Gateway Protocol.  */
    #define IPPROTO_EGP     IPPROTO_EGP
        IPPROTO_PUP = 12,      /* PUP protocol.  */
    #define IPPROTO_PUP     IPPROTO_PUP
        IPPROTO_UDP = 17,      /* User Datagram Protocol.  */
    #define IPPROTO_UDP     IPPROTO_UDP
        IPPROTO_IDP = 22,      /* XNS IDP protocol.  */
    
        IPPROTO_IPV6 = 41,     /* IPv6 header.  */
    #define IPPROTO_IPV6 IPPROTO_IPV6
        IPPROTO_RAW = 255,     /* Raw IP packets.  */
    #define IPPROTO_RAW     IPPROTO_RAW
        IPPROTO_MAX };

    标准端口enum

    enum
      {
        IPPORT_ECHO = 7,        /* Echo service.  */
        IPPORT_DISCARD = 9,     /* Discard transmissions service.  */
        IPPORT_SYSTAT = 11,     /* System status service.  */
        IPPORT_DAYTIME = 13,    /* Time of day service.  */
        IPPORT_NETSTAT = 15,    /* Network status service.  */
        IPPORT_FTP = 21,        /* File Transfer Protocol.  */
        IPPORT_TELNET = 23,     /* Telnet protocol.  */
        IPPORT_SMTP = 25,       /* Simple Mail Transfer Protocol.  */
        IPPORT_TIMESERVER = 37, /* Timeserver service.  */
        IPPORT_NAMESERVER = 42, /* Domain Name Service.  */
        IPPORT_WHOIS = 43,      /* Internet Whois service.  */
        IPPORT_MTP = 57,
    
        IPPORT_TFTP = 69,       /* Trivial File Transfer Protocol.  */
        IPPORT_RJE = 77,
        IPPORT_FINGER = 79,     /* Finger service.  */
        IPPORT_TTYLINK = 87,
        IPPORT_SUPDUP = 95,     /* SUPDUP protocol.  */
    
    
        IPPORT_EXECSERVER = 512,    /* execd service.  */
        IPPORT_LOGINSERVER = 513,   /* rlogind service.  */
        IPPORT_CMDSERVER = 514,
        IPPORT_EFSSERVER = 520,
    
        /* UDP ports.  */
        IPPORT_BIFFUDP = 512,
        IPPORT_WHOSERVER = 513,
        IPPORT_ROUTESERVER = 520,
    
        /* Ports less than this value are reserved for privileged processes.  */
        IPPORT_RESERVED = 1024,
    
        /* Ports greater this value are reserved for (non-privileged) servers.  */
        IPPORT_USERRESERVED = 5000
      };

     ABCD四类网络,常用IP地址

    #define IN_CLASSA(a)        ((((in_addr_t)(a)) & 0x80000000) == 0)
    
    #define IN_CLASSB(a)        ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
    
    #define IN_CLASSC(a)        ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
    
    #define IN_CLASSD(a)        ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
    
    /* Address to accept any incoming messages.  */
    #define INADDR_ANY      ((in_addr_t) 0x00000000)
    /* Address to send to all hosts.  */
    #define INADDR_BROADCAST    ((in_addr_t) 0xffffffff)
    /* Address indicating an error return.  */
    #define INADDR_NONE     ((in_addr_t) 0xffffffff)
    
    /* Network number for local host loopback.  */
    #define IN_LOOPBACKNET      127

    还有IPv6、filter相关结构及函数。

    4. 网络地址二进制与字符串转换 -- arpa/inet.h

    推荐使用inet_pton()或inet_aton(),而非inet_addr()或inet_network(),因为返回值-1代表IP地址255.255.255.255。

    extern int inet_aton (const char *__cp, struct in_addr *__inp) __THROW;
    extern char *inet_ntoa (struct in_addr __in) __THROW;
    
    /* Convert from presentation format of an Internet number in buffer
       starting at CP to the binary network format and store result for
       interface type AF in buffer starting at BUF.  */
    extern int inet_pton (int __af, const char *__restrict __cp,
                  void *__restrict __buf) __THROW;
    
    /* Convert a Internet address in binary network format for interface
       type AF in buffer starting at CP to presentation form and place
       result in buffer of length LEN astarting at BUF.  */
    extern const char *inet_ntop (int __af, const void *__restrict __cp,
                      char *__restrict __buf, socklen_t __len)   __THROW;
    #define servip "192.168.1.103"
    
    inet_pton(AF_INET, servip, &servaddr.sin_addr.s_addr);

    实现二进制网络ip与字符串ip之间的转换,均以inet开头。

    此外arpa还包含ftp.h tftp.h telnet.h nameser.h nameser_compat.h。

    5. netdb.h -- network data base library

    /* All data returned by the network data base library are supplied in
       host order and returned in network order (suitable for use in
       system calls).  */

    提供主机/域名等结构体或函数。

    /* Description of data base entry for a single host.  */
    struct hostent
    {
      char *h_name;         /* Official name of host.  */
      char **h_aliases;     /* Alias list.  */
      int h_addrtype;       /* Host address type.  */
      int h_length;         /* Length of address.  */
      char **h_addr_list;       /* List of addresses from name server.  */
    #if defined __USE_MISC || defined __USE_GNU
    # define    h_addr  h_addr_list[0] /* Address, for backward compatibility.*/
    #endif
    };
    /* Description of data base entry for a single service.  */
    struct servent
    {
      char *s_name;         /* Official service name.  */
      char **s_aliases;     /* Alias list.  */
      int s_port;           /* Port number.  */
      char *s_proto;        /* Protocol to use.  */
    };
    /* Description of data base entry for a single service.  */
    struct protoent
    {
      char *p_name;         /* Official protocol name.  */
      char **p_aliases;     /* Alias list.  */
      int p_proto;          /* Protocol number.  */
    };

    提供的常用函数:

    extern struct hostent *gethostent (void);
    extern struct hostent *gethostbyaddr (const void *__addr, __socklen_t __len,
                          int __type);
    extern struct hostent *gethostbyname (const char *__name);
    
    extern struct servent *getservbyname (const char *__name, const char *__proto);
    extern struct servent *getservbyport (int __port, const char *__proto);
    
    extern struct protoent *getprotobyname (const char *__name);
    extern struct protoent *getprotobynumber (int __proto);

     6. sys/un.h--unix域头文件

    un.h中包含Unix域套接字的地址结构体sockaddr_un。

    #include <sys/un.h>

    #define UNIX_PATH_MAX   108
    
    struct sockaddr_un {
        __kernel_sa_family_t sun_family; /* AF_UNIX */
        char sun_path[UNIX_PATH_MAX];   /* pathname */
    };

    实际地址长度为:offsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1

  • 相关阅读:
    【基础算法】- 全排列
    【基础算法】- 2分查找
    区块链培训
    Static Binding (Early Binding) vs Dynamic Binding (Late Binding)
    test
    No data is deployed on the contract address!
    "throw" is deprecated in favour of "revert()", "require()" and "assert()".
    Variable is declared as a storage pointer. Use an explicit "storage" keyword to silence this warning.
    京都行
    Failed to write genesis block: database already contains an incompatible
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/7073932.html
Copyright © 2011-2022 走看看