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

  • 相关阅读:
    MyBatis(六)缓存机制 之 缓存的相关属性设置
    MyBatis(六)缓存机制 之 缓存机制简介
    MyBatis(五)动态SQL 之 批量操作(插入)
    MyBatis(五)动态SQL 之 批量操作(删除)
    MyBatis(六)缓存机制 之 整合第三方缓存
    MyBatis(六)缓存机制 之 二级缓存
    MyBatis(五)动态SQL 之 批量操作(查询)
    MyBatis(六)缓存机制 之 缓存原理图
    MyBatis(六)缓存机制 之 一级缓存
    MyBatis(五)动态SQL 之 批量操作(更新)
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/7073932.html
Copyright © 2011-2022 走看看