addrinfo& sockaddr结构解析

1 addrinfo

addrinfo结构内容如下:

struct addrinfo {
    int ai_flags;   /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
    int ai_family;  /* PF_xxx */
    int ai_socktype;    /* SOCK_xxx */
    int ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
    socklen_t ai_addrlen;   /* length of ai_addr */
    char    *ai_canonname;  /* canonical name for hostname */
    struct  sockaddr *ai_addr;  /* binary address */
    struct  addrinfo *ai_next;  /* next structure in linked list */
};

1.1 ai_family

ai_family指定了地址族,可取值如下:

取值 含义
AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 协议无关
void print_family(struct addrinfo *aip)
{
    printf(" family ");
    switch (aip->ai_family) {
    case AF_INET:
        printf("inet");
        break;T
    case AF_INET6:
        printf("inet6");
        break;
    case AF_UNIX:
        printf("unix");
        break;
    case AF_UNSPEC:
        printf("unspecified");
        break;
    default:
        printf("unknown");
    }
}

1.2 ai_socketype

取值 含义
SOCK_STREAM 1 数据流协议
SOCK_DGRAM 2 数据报协议
void print_type(struct addrinfo *aip)
{
    printf(" type ");
    switch (aip->ai_socktype) {
    case SOCK_STREAM:
        printf("stream");
        break;
    case SOCK_DGRAM:
        printf("datagram");
        break;
    case SOCK_SEQPACKET:
        printf("seqpacket");
        break;
    case SOCK_RAW:
        printf("raw");
        break;
    default:
        printf("unknown (%d)", aip->ai_socktype);
    }
}

1.3 ai_protocol

取值 含义
IPPROTO_IP 0 IP协议
IPPROTO_IPV4 4 IPv4
IPPROTO_IPV6 41 IPv6
IPPROTO_UDP 17 UDP
IPPROTO_TCP 6 TCP
void print_protocol(struct addrinfo *aip)
{
    printf(" protocol ");
    switch (aip->ai_protocol) {
    case 0:
        printf("default");
        break;
    case IPPROTO_TCP:
        printf("TCP");
        break;
    case IPPROTO_UDP:
        printf("UDP");
        break;
    case IPPROTO_RAW:
        printf("raw");
        break;
    default:
        printf("unknown (%d)", aip->ai_protocol);
    }
}

1.4 ai_flags

取值 含义
AI_PASSIVE 1 被动的,用于bind,通常用于server socket
AI_CANONNAME 2 用于返回主机的规范名称
AI_NUMERICHOST 4 地址为数字串
void print_flags(struct addrinfo *aip)
{
    printf("flags");
    if (aip->ai_flags == 0) {
        printf(" 0");
    } else {
        if (aip->ai_flags & AI_PASSIVE)
            printf(" passive");
        if (aip->ai_flags & AI_CANONNAME)
            printf(" canon");
        if (aip->ai_flags & AI_NUMERICHOST)
            printf(" numhost");
#if defined(AI_NUMERICSERV)
        if (aip->ai_flags & AI_NUMERICSERV)
            printf(" numserv");
#endif
#if defined(AI_V4MAPPED)
        if (aip->ai_flags & AI_V4MAPPED)
            printf(" v4mapped");
#endif
#if defined(AI_ALL)
        if (aip->ai_flags & AI_ALL)
            printf(" all");
#endif
    }
}

1.5 sockaddr

套接字体制二级制表示。详见第2节。

2. sockaddr & sockaddr_in

sockaddr:

struct sockaddr {
    unsigned  short  sa_family;     /* address family, AF_xxx */
    char  sa_data[14];                 /* 14 bytes of protocol address */
};
  • sa_family是地址家族,一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET
  • sa_data是14字节协议地址

此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构:sockaddr_in:

// sockaddr_in(在netinet/in.h中定义):
struct  sockaddr_in {
  short  int  sin_family;                      /* Address family */
  unsigned  short  int  sin_port;       /* Port number */
  struct  in_addr  sin_addr;              /* Internet address */
  unsigned  char  sin_zero[8];         /* Same size as struct sockaddr */
};

struct in_addr {
  __be32 s_addr;
};
  • sin_family指代协议族,在socket编程中只能是AF_INET
  • sin_port存储端口号(使用网络字节顺序)
  • sin_addr存储IP地址,使用in_addr这个数据结构,sin_addr按照网络字节顺序存储IP地址
  • sin_zero是为了让sockaddrsockaddr_in两个数据结构保持大小相同而保留的空字节。

sockaddr_insockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向
sockadd的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息,
在最后用进行类型转换就可以了bzero((char*)&mysock,sizeof(mysock));

//初始化:
mysock; // 结构体名
mysock.sa_family=AF_INET;
mysock.sin_addr.s_addr=inet_addr("192.168.0.1");

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 研究IPv6 socket编程原因: Supporting IPv6 in iOS 9 WWDC2015苹果宣布在...
    li大鹏阅读 7,285评论 7 15
  • 网络模型 物理层 物理层表示的是比特流传输,通常包括串口/COM口、并行/LPT口、USB、网线接口、电话线接口;...
    秋风弄影阅读 699评论 0 2
  • socket通信原理 socket又被叫做套接字,它就像连接到两端的插座孔一样,通过建立管道,将两个不同的进程之间...
    jiodg45阅读 1,111评论 0 1
  • 系统与网络编程 OSI模型 应用层,表示层,会话层,传输层,网络层,数据链路层,物理层 socket 在网络编程中...
    I踏雪寻梅阅读 833评论 0 1
  • 在美丽的海南岛上有那么一个地方,紧靠琼州海峡,椰林遍地,四季花开,她有一个美丽的名字-海口,还有一个热带风情...
    李小婵阅读 474评论 1 1