如何将 sockaddr 结构转换为 sockaddr_in - C++ 网络套接字 ubuntu UDP
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11684008/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how do you cast sockaddr structure to a sockaddr_in - C++ networking sockets ubuntu UDP
提问by mister
I am trying to get the client address, but i am unsure how do i cast the sockaddr structure to sockaddr_in?
我正在尝试获取客户端地址,但我不确定如何将 sockaddr 结构转换为 sockaddr_in?
struct sockaddr_in cliAddr, servAddr;
n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *) cliAddr,sizeof(cliAddr));
//i tried this but it does not work
struct sockaddr cliSockAddr = (struct sockaddr *) cliAddr;
char *ip = inet_ntoa(cliSockAddr.sin_addr);
Thanks in advance! :)
提前致谢!:)
i've found questions that brought me to this step: Getting IPV4 address from a sockaddr structure
我发现了将我带到这一步的问题: 从 sockaddr 结构中获取 IPV4 地址
Sorry to avoid confusion, this is my real implementation where "ci" is an object to store pointers such as sockaddr_in.
很抱歉避免混淆,这是我真正的实现,其中“ci”是一个存储指针的对象,例如 sockaddr_in。
/* receive message */
n = recvfrom(*(ci->getSd()), msg, MAX_MSG, 0,(struct sockaddr *) ci->getCliAddr(),ci->getCliLen());
char *ip = inet_ntoa(ci->getCliAddr().sin_addr);
i will get the following errors:
我会收到以下错误:
udpserv.cpp:166: error: request for member ‘sin_addr' in ‘ci->clientInfo::getCliAddr()', which is of non-class type ‘sockaddr_in*'
回答by bmatheny
I would point out that if this is actually C++ the idiomatic way to do this would be:
我要指出的是,如果这实际上是 C++,那么这样做的惯用方法是:
sockaddr *sa = ...; // struct not needed in C++
char ip[INET6_ADDRSTRLEN] = {0};
switch (sa->sa_family) {
case AF_INET: {
// use of reinterpret_cast preferred to C style cast
sockaddr_in *sin = reinterpret_cast<sockaddr_in*>(sa);
inet_ntop(AF_INET, &sin->sin_addr, ip, INET6_ADDRSTRLEN);
break;
}
case AF_INET6: {
sockaddr_in6 *sin = reinterpret_cast<sockaddr_in6*>(sa);
// inet_ntoa should be considered deprecated
inet_ntop(AF_INET6, &sin->sin6_addr, ip, INET6_ADDRSTRLEN);
break;
}
default:
abort();
}
This sample code handles IPv4 and IPv6 addresses and also would be considered more C++ idiomatic than either of the suggested implementations.
此示例代码处理 IPv4 和 IPv6 地址,并且比任何一个建议的实现都更符合 C++ 习惯。
回答by Some programmer dude
It is actually very simple!
其实很简单!
struct sockaddr *sa = ...;
if (sa->sa_family == AF_INET)
{
struct sockaddr_in *sin = (struct sockaddr_in *) sa;
ip = inet_ntoa(sin->sin_addr);
}
回答by selbie
I think this will compile just fine for you and do what you want.
我认为这对你来说编译得很好并做你想做的事。
struct sockaddr_in cliAddr={}, servAddr={};
socklen_t cliAddrLength = sizeof(cliAddr);
n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *)&cliAddr, &cliAddrLength);