11

クライアントアドレスを取得しようとしていますが、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*’
4

3 に答える 3

27

これが実際に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++ の慣用句と見なされます。

于 2013-09-02T19:23:33.963 に答える
17

それは実際には非常に簡単です!

struct sockaddr *sa = ...;

if (sa->sa_family == AF_INET)
{
    struct sockaddr_in *sin = (struct sockaddr_in *) sa;
    ip = inet_ntoa(sin->sin_addr);
}
于 2012-07-27T08:23:57.287 に答える
3

これはあなたにとってうまくコンパイルされ、あなたが望むことをするだろうと思います。

struct sockaddr_in cliAddr={}, servAddr={};

socklen_t cliAddrLength = sizeof(cliAddr);

n = recvfrom(sd, msg, MAX_MSG, 0,(struct sockaddr *)&cliAddr, &cliAddrLength);
于 2012-07-27T08:34:55.043 に答える