套接字编程,将 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 *
。 &serv_addr
是 struct sockaddr_in *
。套接字 api 用于传递通用地址并让套接字配置和地址头信息(在 sockaddr 中 是),以及由于第三个参数(大小)。简而言之,它是您可能见过的最愚蠢的非继承但行为类似的系统,并且需要强制转换,以免编译器告诉您类型错误。
【参考方案1】:
这里强制转换的目的是什么,将 sockaddr_in 转换为 sockaddr。
sockaddr_in
不会转换为 sockaddr
。 sockaddr_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。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
2-3:套接字(Socket)编程之UDP通信,sockaddr,sockaddr_in,recvfrom,sendto