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

struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。

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 {
unsigned  long  s_addr;
};typedef struct in_addr {
union {struct{unsigned char s_b1,s_b2,s_b3,s_b4;} S_un_b;struct {unsigned short s_w1,s_w2;} S_un_w;unsigned long S_addr;} S_un;
} IN_ADDR;

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

sockaddr_in和sockaddr是并列的结构,指向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");
……
等到要做转换的时候用:
(struct sockaddr*)mysock

通常的用法是:

int sockfd;
struct sockaddr_in my_addr;
sockfd = socket(AF_INET, SOCK_STREAM, 0); my_addr.sin_family = AF_INET; /* 主机字节序 */
my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */
//memset(&my_addr.sin_zero, 0, 8);bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));#define UNIX_PATH_MAX 108struct sockaddr_un {sa_family_t sun_family; /*PF_UNIX或AF_UNIX */char sun_path[UNIX_PATH_MAX]; /* 路径名 */};几点注意:
1:BSD网络软件中包含了两个函数,用来在二进制地址格式和点分十进制字符串格式之间相互转换,但
是这两个函数仅仅支持IPv4。in_addr_t inet_addr(const char *cp);char *inet_ntoa(struct in_addr in);
功能相似的两个函数同时支持IPv4和IPv6const char *inet_ntop(int domain, const void *addr, char *str, socklen_t size);int inet_pton(int domain, const char *str, void *addr);
2:Sockfd是调用socket函数返回的socket描述符,my_addr是一个指向包含有本机IP地址及端口号等信
息的sockaddr类型的指针;addrlen常被设置为sizeof(struct sockaddr)。struct sockaddr结构类型是用来保存socket信息的: struct sockaddr { unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14 字节的协议地址 */
}; sa_family一般为AF_INET,代表Internet(TCP/IP)地址族;sa_data则包含该socket的IP地址和端口号。 另外还有一种结构类型: struct sockaddr_in { short int sin_family; /* 地址族 */ unsigned short int sin_port; /* 端口号 */ struct in_addr sin_addr; /* IP地址 */ unsigned char sin_zero[8]; /* 填充0 以保持与struct sockaddr同样大小 */ };
这个结构更方便使用。sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,
可以用bzero()或memset()函数将其置为零。指向sockaddr_in 的指针和指向sockaddr的指针可以相
互转换,这意味着如果一个函数所需参数类型是sockaddr时,你可以在函数调用的时候将一个指向
sockaddr_in的指针转换为指向sockaddr的指针;或者相反。
3:你只要记住,填值的时候使用sockaddr_in结构,而作为函数的
参数传入的时候转换成sockaddr结构就行了,毕竟都是16个字符
长。struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un };

sockaddr_un
进程间通信的一种方式是使用UNIX套接字,人们在使用这种方式时往往用的不是网络套接字,而是一种称为本地套接字的方式。这样做可以避免为黑客留下后门。

struct sockaddr_un {sa_family_t sun_family; /*PF_UNIX或AF_UNIX */char sun_path[UNIX_PATH_MAX]; /* 路径名 */};
首先这个结构体是用来本地通信用的,并不是什么tcp/ip通信,虽然代码模式上很相似,准确的说是unix
Domain 的通信,二者有本质上的区别,那个sun_path成员也就是担任这个domain(域)的角色了,比如存储
“/tmp/mydomain”这样的东西,再比如A和B之间通信,A应该有一个类似"/tmp/A"(名字可以自己随意起)的
域,B应该有一个类似"/tmp/B"的域,通信时分别向对方的域发送消息,从自己的域接受消息。A和B通信时都
是各自初始化对方的域,而创建本身的套接字的时候是初始化自身的 unix domain的socket通信和网络socket不同的地方在于地址格式不同,用结构体sockaddr_un表示,网络编
程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的
路径,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

创建
使用套接字函数socket创建,不过传递的参数与网络套接字不同。域参数应该是PF_LOCAL或者PF_UNIX,而不能用PF_INET之类。本地套接字的通讯类型应该是SOCK_STREAM或SOCK_DGRAM,协议为默认协议。例如:
 int sockfd;
 sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);

绑定
创建了套接字后,还必须进行绑定才能使用。不同于网络套接字的绑定,本地套接字的绑定的是struct sockaddr_un结构。struct sockaddr_un结构有两个参数:sun_family、sun_path。sun_family只能是AF_LOCAL或AF_UNIX,而sun_path是本地文件的路径。通常将文件放在/tmp目录下。例如:

struct sockaddr_un sun;
 sun.sun_family = AF_LOCAL;
 strcpy(sun.sun_path, filepath);
 bind(sockfd, (struct sockaddr*)&sun, sizeof(sun));

监听
本地套接字的监听、接受连接操作与网络套接字类似。

连接
连接到一个正在监听的套接字之前,同样需要填充struct sockaddr_un结构,然后调用connect函数。

连接建立成功后,我们就可以像使用网络套接字一样进行发送和接受操作了。甚至还可以将连接设置为非阻塞模式,这里就不赘述了。

struct sockaddr与struct sockaddr_in ,struct sockaddr_un的区别和联系相关推荐

  1. struct sockaddr与struct sockaddr in struct sockaddr un的区别和联系

    在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下: typedef unsigned short sa_family_t ...

  2. sockaddr、sockaddr_in、sockaddr_in6的区别及转换

    本文转自:https://blog.csdn.net/albertsh/article/details/80991684 前言 最近在学习网络相关的知识,虽然之前代码写了不少,但是长时间不写难免会忘记 ...

  3. 整理struct sockaddr和struct sockaddr_in

    struct sockaddr定义在/usr/include/linux/socket.h struct sockaddr {unsigned short ss_family;char ss_data ...

  4. struct sockaddr和struct sockaddr_in的强制类型转换

    1. struct sockaddr {unsigned short sa_family;//地址类型char sa_data[14];//协议地址} 2. struct sockaddr_in {u ...

  5. struct sockaddr和struct sockaddr_in区别

    struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址. 一.sockaddr sockaddr在头文件#include <sys/socket. ...

  6. 【C++】Winsock套接字编程,struct sockaddr、sockaddr_in,主机网络字节序

    前一篇关于windows平台下winsock套接字编程的相关api struct sockaddr与struct sockaddr_in 在bind函数,connect函数里提到了套接字编程网络地址信 ...

  7. python 网络编程 struct解包时报错 struct.error: unpack requires a buffer of 4 bytes

    报错信息 D:\Donta_tensorflow-yolov3\python\python.exe D:/10_gitee/network_programming/避障程序信号及图像接收端/20100 ...

  8. c struct 对齐_C中的struct大小| 填充,结构对齐

    c struct 对齐 What we know is that size of a struct is the sum of all the data members. Like for the f ...

  9. linux系统中struct timeval结构体、struct timezone结构体以及gettimeofday函数

    格林尼治时间.协调世界时 间.世界时间.日光节约时间以及时区等介绍: 格林尼治时间(Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台当地的标准时间,因为本初子午 ...

最新文章

  1. layer弹窗在IOS上,被软键盘挤到上边的解决方法
  2. 开源OSS.Social微信项目进阶介绍
  3. 你在用什么思想编码:事务脚本 OR 面向对象?
  4. POJ3348 Cows【凸包+多边形求面积】
  5. Focal Loss 论文笔记
  6. app = Flask(__name__)相关说明
  7. Error:-81024 LR_VUG:The 'QTWeb' type is not supported on win32 platforms
  8. linux C 编译时手动链接遇到的问题(未解决)
  9. 如何将先验知识注入推荐模型
  10. Docker 安装 weblogic12c
  11. Linq-插入insert
  12. python字符串驻留机制_python的内存驻留机制(小数据池)
  13. 【Scratch案例教学】Scratch九九乘法表 少儿编程Scratch创意编程案例教学
  14. vue 的ui组件库
  15. 何香伊的脸儿,战痘经历
  16. C++动态壁纸软件的开发(含源文件)
  17. 测试工程师如何提升自己
  18. 技术驱动创新,带来的创业机遇
  19. RT-thread内核之IO设备管理系统
  20. XP的点滴(C语言)

热门文章

  1. 修复树莓派鼠标移动缓慢迟滞问题
  2. 503 service unavailable 错误怎么解决?503 service unavailable 错误的解决方法。
  3. 杨辉三角 118.杨辉三角 119.杨辉三角Ⅱ(数学解法)
  4. HTML如何设置幻灯片大小和位置,PPT教程:教你如何在PPT母版中统一标题的位置、大小、样式 | 演示说...
  5. 04 TCP/IP协议详解
  6. 威尔逊定理公式的理解
  7. 如何下载北京城区卫星地图高清版大图
  8. 编译原理:LL(1)语法分析器的实现(内含代码详细注释)
  9. Win10 Chinese输入法修复/note
  10. 数字图像处理之频域滤波