一、两种通用socket结构体

1. sockaddr

struct sockaddr {
sa_family_t sa_family; // 地址族
char sa_data[14]; // 存放socket地址值
};

补:由于不同的协议栈的地址值具有不同的含义和长度(如PF_INET6的地址值占用26字节,更不必说PF_UNIX的地址值最大可达到108字节),所以14字节的sa_data根本无法容纳多数协议族的地址值。

2. sockaddr_storage

struct sockaddr_storage {
sa_family_t sa_family; // 地址族
unsigned long int __ss_align; // 用于内存对齐
char __ss_padding[128-sizeof(__ss_align)]; // 提供足够大的空间用于存放地址值
};

这两个通用socket地址结构体显然很不好用,比如设置与获取IP地址和端口号就需要执行繁琐的位操作。所以,Linux为各个协议族提供了专门的socket地址结构体。

二、专用socket结构体

1. sockaddr_in

struct sockaddr_in {
sa_family_t sin_family; // 地址族
u_int16_t sin_port; // 端口号
struct in_addr sin_addr; // IPv4地址结构体
}; struct in_addr {
u_int32_t s_addr; // IPv4地址
};

2. sockaddr_in6

struct sockaddr_in6 {
sa_family_t sin6_family; // 地址族
u_int16_t sin6_port; // 端口号
struct in6_addr sin6_addr; // IPv6地址结构体
u_int32_t sin6_flowinfo; // 流信息
u_int32_t sin6_scope_id; // scope ID
}; struct in6_addr {
unsigned char sa_addr[16]; // IPv6地址
};

  

3. sockaddr_un

struct sockaddr_un {
sa_family_t sin_family; // 地址族
char sun_path[108]; // 文件路径名
};

所有专用socket地址(以及sockaddr_storage)类型的变量在实际使用时都需要转化为通用socket地址类型sockaddr,因为所有socket编程接口使用的地址参数的类型都是sockaddr。

三、余音绕梁

1. socket地址结构体大小的数据类型为:socklen_t

typedef uint32_t socklen_t;

2. 为何socket编程接口使用的地址参数的类型是sockaddr?

因为socket编程接口需要处理sockaddr_in、sockaddr_in6、sockaddr_un等socket地址结构,为了满足这些需求,于是socket编程接口中的指针参数便指向通用socket地址结构。言下之意就是,我们只需知道sockaddr存在的唯一用途就是对指向特定于协议的socket地址结构体的指针执行强制类型转换。

3. sockaddr_storage结构体往往用于事先不知道地址族的类型这一情况

/* 获取socket的地址族 */
int getFamily(int fd)
{
struct sockaddr_storage ss;
socklen_t len = sizeof(ss);
getsockname(fd, (struct sockaddr*)&ss, &len);
return ss.sa_family;
}

补:既然事先不知道要分配的socket地址结构体的类型,我们只能采用sockaddr_storage这个通用socket地址结构体,因为它能够承载系统支持的任何socket地址结构体。也就是说,它能够容纳下sockaddr_in6结构体的26字节的地址值,也能够容纳下sockaddr_un结构体的108字节的文件路径名。  

  

  

  

2. socket结构体——表示socket地址的更多相关文章

  1. struct socket结构体详解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weiguozhihui.blog.51cto.com/3060615/15852 ...

  2. Socket 结构体

    proto socket 关联结构: { .type = SOCK_STREAM, .protocol = IPPROTO_TCP, .prot = &tcp_prot, .ops = &am ...

  3. 通过 struct 成员地址 获取 struct 结构体地址

    1. 问题描述: 现在定义了一个结构体: struct Foo { int a; int b; }; Foo foo; 假如由于函数传参等原因,现在程序只能拿到 foo.b 的地址,这时想通过某种方法 ...

  4. ARM单片机的头文件如何用结构体定义地址

    下面我们以ARM Cortex-M0内核单片机LPC1114的头文件lpc11xx.h文件进行说明. 1.先说两句 lpc11xx.h文件是lpc11xx系列单片机包含的头文件.这个文件的作用和51单 ...

  5. 由结构体成员地址计算结构体地址——list_entry()原理详解

    #define list_entry(ptr, type, member) container_of(ptr, type, member) 在进行编程的时候,我们经常在知道结构体地址的情况下,寻找其中 ...

  6. Linux中的两个经典宏定义:获取结构体成员地址,根据成员地址获得结构体地址;Linux中双向链表的经典实现。

    倘若你查看过Linux Kernel的源码,那么你对 offsetof 和 container_of 这两个宏应该不陌生.这两个宏最初是极客写出的,后来在Linux内核中被推广使用. 1. offse ...

  7. Go第六篇之结构体剖析

    Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. Go 语言中的类型可以被实例化,使用new或&a ...

  8. 06. Go 语言结构体

    Go语言结构体(struct) Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. Go 语言中的类 ...

  9. C语言中的结构体

    用户自己建立自己的结构体类型 1.  定义和使用结构体变量 (1).结构体的定义 C语言允许用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体. (2).声明一个结构体类型的一般形式为: ...

随机推荐

  1. 竞赛题解 - NOIP2018 赛道修建

    \(\mathcal {NOIP2018}\) 赛道修建 - 竞赛题解 额--考试的时候大概猜到正解,但是时间不够了,不敢写,就写了骗分QwQ 现在把坑填好了~ 题目 (Copy from 洛谷) 题 ...

  2. JsonCpp在vs中使用

    Jsoncpp是c++生成和解析Json数据的跨平台开源库.下面简介如何在vs中使用. 1.官网下载.https://sourceforge.net/projects/jsoncpp/解压文件得到js ...

  3. JavaScript 时间对象 date()

    getYear() 获得的是距离1900年过了多少年 var d = new Date(); document.write(d+"<br />"); document. ...

  4. 使用JDK开发WebServrice案例

    使用JDK开发WebServrice案例: 一.开发WebService服务器端 第一步:创建Java工程 ,创建相应的包(服务端)使用JDK开发(1.6以上版本) 第二步:建一个接口WebServi ...

  5. npm install路径

    我们在webpack项目中使用npm install命令安装很多模块 但是很多时候都不知道这些模块安装在哪里,想要删除的时候找不到,所有想要明确的知道npm的安装路径 首先,npm install 安 ...

  6. PredicateBuilder

    using System; using System.Linq; using System.Linq.Expressions; namespace Oyang.Tool { public static ...

  7. Linux的基础命令大全

    linux的基础命令大全 1.shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口(命令解释器) ls -al /bin/sh   ls -al /bin/bash 查看这些shell的 ...

  8. Java学习笔记二十:Java中的内部类

    Java中的内部类 一:什么是内部类: (1).什么是内部类呢? 内部类( Inner Class )就是定义在另外一个类里面的类.与之对应,包含内部类的类被称为外部类. (2).那为什么要将一个类定 ...

  9. java 程序文本文档形式的编写,编译,及运行

    一.程序的编写 1.在指定路径下新建文本文档 如在f盘新建了一个名为demo的文件夹,在该文件夹路径下新建了一个文本文档 2.打开文本文档,进行编写,例如: 3.保存 选择文件另存为,文件名称为你创建 ...

  10. 初识Tarjan

    Tarjan,一个十分有用的东西,可以求有向图的强连通分量,复杂度达到O(V+E). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节 ...