网络编程入门01

实现网络库的一些基石

一些基本的变量定义

sa_family_t unsigned integer type
socklen_t an integer type of width of at least 32 bits
in_addr_t uint32_t

IPv4: struct sockaddr_in, 16个字节

struct sockaddr_in {
     sa_family_t sin_family;             /* AF_INET */
     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) -
                            sizeof (sa_family_t) -
                            sizeof (in_port_t) -
                            sizeof (struct in_addr)];
};
typedef uint32_t in_addr_t;
struct in_addr  {
    in_addr_t s_addr;                    /* IPv4 address */
};

IPv6: struct sockaddr_in6, 28个字节

struct sockaddr_in6 {
    sa_family_t sin6_family;    /* AF_INET6 */
    in_port_t sin6_port;        /* Transport layer port # */
    uint32_t sin6_flowinfo;     /* IPv6 flow information */
    struct in6_addr sin6_addr;  /* IPv6 address */
    uint32_t sin6_scope_id;     /* IPv6 scope-id */
};
struct in6_addr {
    union {
        uint8_t u6_addr8[16];
        uint16_t u6_addr16[8];
        uint32_t u6_addr32[4];
    } in6_u;

    #define s6_addr                 in6_u.u6_addr8
    #define s6_addr16               in6_u.u6_addr16
    #define s6_addr32               in6_u.u6_addr32
};

3. 通用结构体1: struct sockaddr, 16个字节

struct sockaddr { 
          sa_family_t sa_family;       /* Address family */
          char sa_data[14];            /* protocol-specific address */
};

4. 通用结构体2: struct sockaddr_storage,128个字节

/* Structure large enough to hold any socket address 
(with the historical exception of AF_UNIX). 128 bytes reserved.  */

#if ULONG_MAX > 0xffffffff
# define __ss_aligntype __uint64_t
#else
# define __ss_aligntype __uint32_t
#endif
#define _SS_SIZE        128
#define _SS_PADSIZE     (_SS_SIZE - (2 * sizeof (__ss_aligntype)))

struct sockaddr_storage
{
    sa_family_t ss_family;      /* Address family */
    __ss_aligntype __ss_align;  /* Force desired alignment.  */
    char __ss_padding[_SS_PADSIZE];
};

通用结构是为了提高更好的兼容性,主要为了兼容IPV4 IPV6

struct sockaddr_storage addr;
memset(&addr, 0, sizeof(struct sockaddr_storage));
if (isIPv6 == TRUE)
{
    struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr;
    addr_v6->sin6_family = AF_INET6;
    addr_v6->sin6_port = 1234;
    inet_pton(AF_INET6, “2001:3211::1”, &(addr_v6->sin6_addr));
}
else
{
    struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr;
    addr_v4->sin_family = AF_INET;
    addr_v4->sin_port = 1234;
    inet_aton(“192.168.1.228”, &(addr_v4->sin_addr));
}

sendto(sock, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));

结构图
实习了,慢慢的走入公司,才知道课本里学的那么简单。在学校里的作业,网络模块只是简单的socket收发信息,在实际的工程中,不会直接使用,都是用封装好易用的库,并且要加入并发编程支持高并发,不过要读懂网络库的实现,也必须从最基本的socket api了解。路漫漫其修远兮。
参考资料:
tanghuiming0713

posted @ 2019-07-26 12:30  just4fun  阅读(157)  评论(0编辑  收藏  举报