网络编程-sockaddr和sockaddr_in的区别

本文介绍了套接字编程中sockaddr和sockaddr_in的区别。sockaddr是一个通用的地址结构,用于不同协议族,而sockaddr_in是针对以太网的,包含了更具体的地址和端口信息。程序员通常使用sockaddr_in填充地址和端口,然后转换为sockaddr传递给系统调用。示例代码展示了如何使用sockaddr_in创建和连接套接字。

sockaddr和sockaddr_in的区别_tao546377318的博客-优快云博客

套接字编程需要指定套接字的地址作为参数,不同的协议族有不同的地址结构定义方式。这些地址结构通常以sockeaddr_开头,每一个协议族有一个唯一的后缀,例如对于以太网,其结构名称为sockaddr_in.

 1.通用套接字数据结构

    通用的套接字地址类型的定义如下,它可以在不同协议族之间进行强制转换。

include <netinet/in.h>  
  
struct sockaddr {  
    unsigned short    sa_family;    // 2 bytes address family, AF_xxx  unsiged short
    char              sa_data[14];     // 14 bytes of protocol address  
};  


    在网络程序设计中所使用的函数中几乎所有的套接字函数都用这个结构作为参数,例如bin()函数的原型为:
int bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
  2.实际使用的套接字数据结构
    在使用结构struct sockaddr 不方便进行设置,在以太网设置,在以太网中,一般使用结构struct sockaddr_in进行设置,这个结构如下所示:

struct sockaddr_in {  
    short            sin_family;       // 2 bytes e.g. AF_INET, AF_INET6  
    unsigned short   sin_port;    // 2 bytes e.g. htons(3490)  
    struct in_addr   sin_addr;     // 4 bytes see struct in_addr, below  
    char             sin_zero[8];     // 8 bytes zero this if you want to  
};  
  
struct in_addr {  
    unsigned long s_addr;          // 4 bytes load with inet_pton()  
};  


 3. sockaddr和sockaddr_in包含的数据都是一样的,但他们在使用上有区别:
程序员不应操作sockaddr,sockaddr是给操作系统用的
程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。


 4.一般的用法为:

   程序员把类型、ip地址、端口填充sockaddr_in结构体,然后强制转换成sockaddr,作为参数传递给系统调用函数

网络编程中一段典型的代码为:

int sockfd;  
struct sockaddr_in servaddr;  
  
sockfd = Socket(AF_INET, SOCK_STREAM, 0);  
  
/* 填充struct sockaddr_in */  
bzero(&servaddr, sizeof(servaddr));  
servaddr.sin_family = AF_INET;  
servaddr.sin_port = htons(SERV_PORT);  
inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);  
  
/* 强制转换成struct sockaddr */  
connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));


————————————————
版权声明:本文为优快云博主「Ijuan_0712」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/tao546377318/article/details/72780685



other:

Type casting of sockaddr to sockaddr_in and retrieval of ipv4 using inet_ntoa
 

char * ip = inet_ntoa(((struct sockaddr_in *)sockaddr)->sin_addr);
你贴出的这段代码是 C 语言中用于描述 **IPv4 网络地址信息** 的结构体 `struct sockaddr_in`,这是在网络编程中非常基础且重要的结构。 --- ### 代码解析: ```c struct sockaddr_in { __SOCKADDR_COMMON (sin_); in_port_t sin_port; /* 端口号 */ struct in_addr sin_addr; /* IP 地址 */ /* 填充字段,使该结构体与 struct sockaddr 大小一致 */ unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; }; ``` #### 各字段详解: 1. `__SOCKADDR_COMMON (sin_);` - 这是一个宏,用于定义通用地址族字段(`sa_family_t sin_family;`),通常展开为: ```c sa_family_t sin_family; ``` - 用于指定地址族(如 `AF_INET` 表示 IPv4)。 2. `in_port_t sin_port;` - 存储端口号(16 位),注意使用的是 **网络字节序(大端)**,通常需要使用 `htons()` 转换。 3. `struct in_addr sin_addr;` - 存储 IPv4 地址(32 位),结构体定义如下: ```c struct in_addr { uint32_t s_addr; // 32-bit IPv4 address in network byte order }; ``` 4. `unsigned char sin_zero[...];` - 填充字段,使 `sockaddr_in` 通用结构体 `sockaddr` 保持相同大小(通常是 16 字节)。 - 在使用时通常设为 0。 --- ### 使用示例(设置服务器地址): ```c struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; // IPv4 server_addr.sin_port = htons(8080); // 端口 8080 inet_pton(AF_INET, "192.168.1.1", &server_addr.sin_addr); // IP 地址 ``` --- ### 与 `struct sockaddr` 的关系: - `struct sockaddr` 是通用的 socket 地址结构,用于系统调用如 `bind()`、`connect()`、`accept()` 等。 - `struct sockaddr_in` 是其 IPv4 特定实现,使用时经常需要进行类型转换: ```c struct sockaddr_in addr; bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)); ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值