网络编程基础——数据结构

前言:算是开了「网络编程」的坑,以后的方向是做安全,到毕业主要钻研两个方向——计算机网络和操作系统,加油。我正在读的书在这里,博客大部分内容也是来自这里

0X00 与网络编程相关的数据结构

  • socket 描述符

与普通的文件描述符一样都是 int 类型

  • addrinfo struct
struct addrinfo
{
    int ai_flags;             // AI_PASSIVE, AI_CANONNAME, etc.
    int ai_family;            // AF_INET, AF_INET6, AF_UNSPEC
    int ai_socktype;          // SOCK_STREAM, SOCK_DGRAM
    int ai_protocol;          // use 0 for "any"
    size_t ai_addrlen;        // size of ai_addr in bytes
    struct sockaddr *ai_addr; // struct sockaddr_in or _in6
    char *ai_canonname;       // full canonical hostname
    struct addrinfo *ai_next; // linked list, next node
};

一般通过 getaddrinfo() 得到 addrinfo,其中:

ai 就是 addrinfo 的意思。ai_family 用来设置 ipv4,ipv6,还是都可以。socket 有多种类型 ai_socktype 就是用来设置类型。使用 getaddrinfo() 可能有多个结果,所以它可能有一串 addrinfoai_next 用来指向下一个 addrinfo

  • sockaddr
struct sockaddr {    
    unsigned short    sa_family;    // address family, AF_xxx    
    char              sa_data[14];  // 14 bytes of protocol address
};

上面还有一个 sockaddr,sockaddr 的结构如上。sa_data 包含 socket 的目标地址和端口号。

但是这样写太麻烦了,端口号和地址写在一起了,又提出了一个可以兼容这个结构的 sockaddr_in(都是 16 字节)

  • sockaddr_in
// ipv4
struct sockaddr_in {    
    short int          sin_family;  // Address family, AF_INET    
    unsigned short int sin_port;    // Port number    
    struct in_addr     sin_addr;    // Internet address    
    unsigned char      sin_zero[8]; // Same size as struct sockaddr
};

在这个结构中,sin_zero 是用来填充大小的,为了和 sockaddr 大小一样,初始化的时候使用 memset() 全部设置为 0,还有一个 in_addr 结构

  • in_addr
// ipv4
struct in_addr {    
    uint32_t s_addr; // that's a 32-bit int (4 bytes)
};
  • 我们再来看看 ipv6
truct sockaddr_in6 {    
    u_int16_t       sin6_family;   // address family, AF_INET6    
    u_int16_t       sin6_port;     // port number, Network Byte Order
    u_int32_t       sin6_flowinfo; // IPv6 flow information    
    struct in6_addr sin6_addr;     // IPv6 address    
    u_int32_t       sin6_scope_id; // Scope ID
};
struct in6_addr {    
    unsigned char   s6_addr[16];   // IPv6 address
};

这个数据结构我没怎么弄懂,先放着吧,等我学深入了就好了

struct sockaddr_storage {    
    sa_family_t  ss_family;     // address family    
    // all this is padding, implementation specific, ignore it:    
    char      __ss_pad1[_SS_PAD1SIZE];    
    int64_t   __ss_align;    
    char      __ss_pad2[_SS_PAD2SIZE];
};

  • inet_ntoa() 用法
struct sockaddr_in sa; // IPv4
struct sockaddr_in6 sa6; // IPv6
inet_pton(AF_INET, "10.12.110.57", &(sa.sin_addr)); // IPv4
inet_pton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr)); // IPv6

用法如下:


#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main()
{
    // IPv4:
    char ip4[INET_ADDRSTRLEN];
    struct sockaddr_in sa;
    // space to hold the IPv4 string
    // pretend this is loaded with something
    inet_ntop(AF_INET, &(sa.sin_addr), ip4, INET_ADDRSTRLEN);
    printf("The IPv4 address is: %s\n", ip4);
    // IPv6:
    char ip6[INET6_ADDRSTRLEN]; // space to hold the IPv6 string
    struct sockaddr_in6 sa6;
    // pretend this is loaded with something
    inet_ntop(AF_INET6, &(sa6.sin6_addr), ip6, INET6_ADDRSTRLEN);
    printf("The address is: %s\n", ip6);
    return 0;
}

将 sockaddr_in 转换成字符串

下一篇文章将介绍常见 API

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容