我正在尝试获取客户端地址,但我不确定如何将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);
提前致谢! 🙂
我发现了一些问题,让我走到这一步: 从sockaddr结构获取IPV4地址
对不起,为了避免混淆,这是我真正的实现,其中“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);
我会得到以下错误:
udpserv.cpp:166: error: request for member 'sin_addr' in 'ci->clientInfo::getCliAddr()', which is of non-class type 'sockaddr_in*'
其实很简单!
struct sockaddr *sa = ...; if (sa->sa_family == AF_INET) { struct sockaddr_in *sin = (struct sockaddr_in *) sa; ip = inet_ntoa(sin->sin_addr); }
我会指出,如果这实际上是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(); }
这个示例代码处理IPv4和IPv6地址,也被认为比任何一个建议的实现都更多的C ++惯用法。
我认为这会为你编译得很好,做你想做的事情。
struct sockaddr_in cliAddr={}, servAddr={}; socklen_t cliAddrLength = sizeof(cliAddr); n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *)&cliAddr, &cliAddrLength);