套接字编程,将 sockaddr_in 转换为 sockaddr。为啥?

Posted

技术标签:

【中文标题】套接字编程,将 sockaddr_in 转换为 sockaddr。为啥?【英文标题】:Socket Programming, Casting sockaddr_in to sockaddr. Why?套接字编程,将 sockaddr_in 转换为 sockaddr。为什么? 【发布时间】:2021-05-18 06:30:19 【问题描述】:

这是一个来自客户端的示例套接字编程 sn-p。我的问题围绕将 sockaddr_in 转换为 sockaddr 的类型转换。我的问题是,为什么那里有必要进行铸造,那里到底发生了什么?

#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define PORT 8080
int main ( int argument, char const *argv[] )

int obj_socket = 0, reader;
struct sockaddr_in serv_addr;
char *message = "A message from Client !";
char buffer[1024] = 0;
if (( obj_socket = socket (AF_INET, SOCK_STREAM, 0 )) < 0)

printf ( "Socket creation error !" );
return -1;

serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if(inet_pton ( AF_INET, "127.0.0.1", &serv_addr.sin_addr)<=0)

printf ( "\nInvalid address ! This IP Address is not supported !\n" );
return -1;

if ( connect( obj_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr )) < 0) // <--- QUESTION ABOUT THIS LINE

Printf ( "Connection Failed : Can't establish a connection over this socket !" );
return -1;

send ( obj_socket , message , strlen(message) , 0 );
printf ( "\nClient : Message has been sent !\n" );
reader = read ( obj_socket, buffer, 1024 );
printf ( "%s\n",buffer );
return 0;

我一直在阅读文档并浏览头文件以了解结构,但最后一件事我无法理解。

标头定义了 sockaddr 结构,其中包括 至少有以下成员: sa_family_t sa_family 地址族 char sa_data[] 套接字地址(变长数据)

头应定义 sockaddr_in 结构, 至少应包括以下成员: sa_family_t sin_family AF_INET。 in_port_t sin_port 端口号。 struct in_addr sin_addr IP 地址。

我的问题是,在这行代码中:

if ( connect( obj_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr )) < 0)

这里将 sockaddr_in 转换为 sockaddr 的这种转换的目的是什么。我知道必须在这里投射,但我想知道为什么会这样?谢谢

【问题讨论】:

套接字 API 是古老的,并且是用 C 语言编写的。因此,您会发现一些不再常见的 API 决策(尤其是在 C++ 中)。 O.T.:完全没有缩进。我猜你正在复制/粘贴到智能手机中。此外,我看到编译器可能会抱怨的Printf。 ;-) 我已经指定了我之前提到的演员表。我感谢您的关注。需要明确的是,连接时 - 代码将 sockaddr_in 转换为 sockaddr *。我的问题是为什么会发生这种情况,背后的原因是什么? 这可能会解决您的一些疑问***.com/a/42190913/4885321 connect 要求它的第二个参数是struct sockaddr *&amp;serv_addrstruct sockaddr_in *。套接字 api 用于传递通用地址并让套接字配置和地址头信息(在 sockaddr 中 ),以及由于第三个参数(大小)。简而言之,它是您可能见过的最愚蠢的非继承但行为类似的系统,并且需要强制转换,以免编译器告诉您类型错误。 【参考方案1】:

这里强制转换的目的是什么,将 sockaddr_in 转换为 sockaddr。

sockaddr_in 不会转换为 sockaddrsockaddr_in* 被转换为 sockaddr*

该转换已完成,因为正在调用的函数 connect 不接受 sockaddr_in* 参数,而是接受 sockaddr*


附:我建议不要手动创建sockaddr_in,而是使用getaddrinfo 来创建它。

P.P.S char *message = "A message from Client !"; 在 C++ 中格式不正确。您发布的代码似乎是 C 而不是 C++。

【讨论】:

感谢您的回复。这消除了我的疑虑。对于未来的读者,我将在此评论中嵌入连接功能:int connect(int socket, const struct sockaddr *address, socklen_t address_len);

以上是关于套接字编程,将 sockaddr_in 转换为 sockaddr。为啥?的主要内容,如果未能解决你的问题,请参考以下文章

sockaddr和sockaddr_in的区别

sockaddr和sockaddr_in的区别

2-3:套接字(Socket)编程之UDP通信,sockaddr,sockaddr_in,recvfrom,sendto

网络编程——sockaddr 与 sockaddr_in

linux 网络编程 2---(TCP编程)

转载:socket网络编程之sockaddr与sockaddr_in的区别