一、两种通用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. 免安装版MySQL8数据库的安装

    [环境准备] PC版本:Windows10企业版.64位操作系统 数据库:MySQL8.0.12-win64.zip免安装版 [彻底卸载已安装的MySQL数据库] 由于系统中MySQL数据库的卸载不彻 ...

  2. 06.升级git版本及命令学习

    博客为日常工作学习积累总结: 1.升级git版本: 参考博客:https://blog.csdn.net/yuexiahunone/article/details/78647565由于新的版本可以使用 ...

  3. jdk11新特性

    JDK 11主要特性一览 jdk11即将在9月25号发布正式版.确定的新特性包括以下17个 181 嵌套类可见性控制 309 动态文件常量 315 改进 Aarch64 Intrinsics 318 ...

  4. Java 面试题 百度/参考的答案

    "a=b"和"a.equals(b)"有什么区别? 如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b 指向的是堆中的同一个对象 ...

  5. C#远程连接postgresql数据库

    第一次在项目中遇到远程访问postgresql数据库的,当时经常会出现连接数据库的错误,连接字符串出现乱码现象 解决方案 在配置文件中添加连接字符串 <add key="Informa ...

  6. 集合之Map

    Map:存放键值对,根据键对象找对应的值对象.键不能重复!Map键不能重复,有唯一性,一般通过键找对应的的值Map集合的特点: 1.具有映射关系 2.两列 3.一列要唯一 一列可以重复 键类似于 Se ...

  7. try catch finally 中 returne的执行顺序

    结论:1.不管有没有出现异常,finally块中代码都会执行:2.当try和catch中有return时,finally仍然会执行:3.finally是在return后面的表达式运算后执行的(此时并没 ...

  8. python基础 抽象类(接口类)

    Python中没有接口.接口类,抽象类:定义 制定一个规范 #必须要导入from abc import ABCMeta,abstractmethod class Payment(metaclass = ...

  9. [NOIP2017]逛公园(DP)

    先spfa一遍处理出d[]数组,(从n开始bfs一遍标记可以达到n的点) 题意即,在走最短路的基础上,可以最多多走K长度的路径, 考虑DP,每次剩余可走的长度会因决策而改变,所以考虑dp[i][j]为 ...

  10. AngularJS-Learning ui-router angular-transitions

    https://github.com/mgechev/AngularJS-Learning https://github.com/angular-ui/ui-router https://github ...