结构体addrinfo, sockaddr, sockaddr_in的区别
struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址。
一、sockaddr
sockaddr在头文件#include <sys/socket.h>中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了,如下:
- struct sockaddr {
- sa_family_t sin_family;//地址族
- char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息
- };
二、sockaddr_in
sockaddr_in在头文件#include<netinet/in.h>或#include <arpa/inet.h>中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中,如下:
sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO)。
三、总结
二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。
sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。
sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。
例子如下:
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- int main(int argc,char **argv)
- {
- int sockfd;
- struct sockaddr_in mysock;
- sockfd = socket(AF_INET,SOCK_STREAM,0); //获得fd
- bzero(&mysock,sizeof(mysock)); //初始化结构体
- mysock.sin_family = AF_INET; //设置地址家族
- mysock.sin_port = htons(800); //设置端口
- mysock.sin_addr.s_addr = inet_addr("192.168.1.0"); //设置地址
- bind(sockfd,(struct sockaddr *)&mysock,sizeof(struct sockaddr); /* bind的时候进行转化 */
- ... ...
- return 0;
- }
题外话,两个函数 htons() 和 inet_addr()。
htons()作用是将端口号由主机字节序转换为网络字节序的整数值。(host to net)
inet_addr()作用是将一个IP字符串转化为一个网络字节序的整数值,用于sockaddr_in.sin_addr.s_addr。
inet_ntoa()作用是将一个sin_addr结构体输出成IP字符串(network to ascii)。比如:
printf("%s",inet_ntoa(mysock.sin_addr));
- 1
htonl()作用和htons()一样,不过它针对的是32位的(long),而htons()针对的是两个字节,16位的(short)。
与htonl()和htons()作用相反的两个函数是:ntohl()和ntohs()。
addrinfo结构体原型
int ai_flags; //AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST
int ai_family; //AF_INET,AF_INET6
int ai_socktype; //SOCK_STREAM,SOCK_DGRAM
int ai_protocol; //IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 etc.
size_t ai_addrlen; //must be zero or a null pointer
char* ai_canonname; //must be zero or a null pointer
struct sockaddr* ai_addr; //must be zero or a null pointer
struct addrinfo* ai_next; //must be zero or a null pointer
}
其中ai_flags、ai_family、ai_socktype说明如下:
参数 取值 值 说明
ai_family AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 协议无关
ai_protocol IPPROTO_IP 0 IP协议
IPPROTO_IPV4 4 IPv4
IPPROTO_IPV6 41 IPv6
IPPROTO_UDP 17 UDP
IPPROTO_TCP 6 TCP
ai_socktype SOCK_STREAM 1 流
SOCK_DGRAM 2 数据报
ai_flags AI_PASSIVE 1 被动的,用于bind,通常用于server socket
AI_CANONNAME 2
AI_NUMERICHOST 4 地址为数字串
对于ai_flags值的说明:
AI_NUMERICHOST | AI_CANONNAME | AI_PASSIVE
如上表所示,ai_flags的值范围为0~7,取决于程序如何设置3个标志位,比如设置ai_flags为 “AI_PASSIVE|AI_CANONNAME”,ai_flags值就为3。三个参数的含义分别为:
(1)AI_PASSIVE当此标志置位时,表示调用者将在bind()函数调用中使用返回的地址结构。当此标志不置位时,表示将在connect()函数调用中使用。当节点名位NULL,且此标志置位,则返回的地址将是通配地址。如果节点名NULL,且此标志不置位,则返回的地址将是回环地址。
(2)AI_CANNONAME当此标志置位时,在函数所返回的第一个addrinfo结构中的ai_cannoname成员中,应该包含一个以空字符结尾的字符串,字符串的内容是节点名的正规名。
(3)AI_NUMERICHOST当此标志置位时,此标志表示调用中的节点名必须是一个数字地址字符串。
结构体addrinfo, sockaddr, sockaddr_in的区别的更多相关文章
- C结构体、C++结构体、C++类的区别
先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...
- 关于c#的结构体struct与class的区别
C# 结构体 struct C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: 1.结构是值类型,它在栈中分配空间:而类是引用类型,它在堆中 ...
- MATLAB 单元数组 cell 和结构体 struct 的用法以及区别
1. 前言 Matlab单元数组cell和结构体struct都可以将不同类型的相关数据集成到一个单一的变量中,使得大量的相关数据的处理变得非常简单而且方便.但是,需要注意的是,单元数组和结构体只是承载 ...
- C语言结构体指针与结构体变量作形参的区别
区别 结构体变量 结构体变量作为形参,传递的是结构体变量本身,是一种值传递 形参结构体变量成员值的改变不影响对应的实参构体变量成员值的改变 结构体指针 结构体指针作为函数参数,传递的是指向结构体变量的 ...
- C++结构体定义和C的区别
对于C来说,struct定义的结构体不是一种数据类型,所以每次声明的时候需要加上struct让编译器知道这是结构体,为了不每次都加上struct关键字,可以在定义结构体的时候加上typedef关键字: ...
- 结构体sockadrr、sockaddr_in、in_addr的定义
/* Internet address. */typedef uint32_t in_addr_t;struct in_addr { in_addr_t s_addr; }; typed ...
- socket编程——sockaddr_in结构体操作
sockaddr结构体 sockaddr的缺陷: struct sockaddr 是一个通用地址结构,这是为了统一地址结构的表示方法,统一接口函数,使不同的地址结构可以被bind() , connec ...
- TinyHttpd中sockaddr与struct sockaddr_in的区别
上午学习TinyHttpd的源码,sockaddr 结构体以前没接触过, 在网络编程中经常用到struct sockaddr和struct sockaddr_in,这里简单介绍. 在linux环境下, ...
- IPv4地址结构体sockaddr_in详解
sockaddr_in结构体定义 struct sockaddr_in { sa_family_t sin_family; //地址族(Address Family) uint16_t sin_por ...
随机推荐
- [算法&数据结构]深度优先搜索(Depth First Search)
深度优先 搜索(DFS, Depth First Search) 从一个顶点v出发,首先将v标记为已遍历的顶点,然后选择一个邻接于v的尚未遍历的顶点u,如果u不存在,本次搜素终止.如果u存在,那么从u ...
- 深入理解group by 语句的执行顺序 from→where→group by→select(含聚合函数)
由于之前没有对group by 语句的执行顺序(执行原理)做深入的了解,所以导致在实际应用过程中出现了一些问题.举个简单的粟子,比如一个表testA中的所有数据如下图: 我现在想从testA中查询us ...
- js 学习之路9:运算符
1. 算数运算符 运算符 描述 例子 结果 + 加 x=y+2 x=7 - 减 x=y-2 x=3 * 乘 x=y*2 x=10 / 除 x=y/2 x=2.5 % 求余数 (保留整数) x=y%2 ...
- Windows下查看硬连接引用技术
Win10有了bash,可以方便的进入并用ll查看文件的硬连接数. 但是用powershell直接查看就比较麻烦了,比较曲折的找到了方法: fsutil hardlink list [filename ...
- Linux(CentOS7)yum安装卸载命令,离线下载安装包
一.Linux版本 二.yum安装 比如安装vim编辑器,y是自动应答,即默认一路确认,不用中途确认 yum install -y vim 三.yum卸载 比如卸载掉刚刚安装的vim yum eras ...
- c++11の关联容器
一.关联容器 C++的容器类型可以分为顺序容器和关联容器两大类.对于关联容器,主要有map和set,对于这两种,根据不同的维度,衍生出了8种容器 map ...
- 数据结构学习之栈求解n皇后问题
数据结构学习之栈求解n皇后问题 0x1 目的 深入掌握栈应用的算法和设计 0x2 内容 编写一个程序exp3-8.cpp求解n皇后问题. 0x3 问题描述 即在n×n的方格棋盘上,放置n个皇后 ...
- I used to know
曾经我以为, 这世上满是痛苦. 必须靠坚强过活, 必须在深夜的被窝里默默痛哭. 后来我才发现, 这个世上, 只有快乐.
- Python学习步骤如何安排?
一.清楚学习目标 无论是学习什么知识,都要有一个对学习目标的清楚认识. 只有这样才能朝着目标持续前进,少走弯路,从学习中得到不断的提升,享受python学习计划的过程. 二.基本python 知识学习 ...
- dva
import React, { PureComponent } from "react"; import { Chart, Geom, Axis, Tooltip, Coord, ...