Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do you cast sockaddr structure to a sockaddr_in - C++ networking sockets ubuntu UDP

I am trying to get the client address, but i am unsure how do i cast the sockaddr structure to 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


Sorry to avoid confusion, this is my real implementation where "ci" is an object to store pointers such as 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*’
like image 555
mister Avatar asked Jul 27 '12 08:07

mister


People also ask

What is struct Sockaddr_in in C?

The “sockaddr_in” structure is very commonly used in socket programming in the C programming language. This structure allows you to bind a socket with the desired address so that a server can listen to the clients' connection requests.

Which of the following is commonly used to read an IP address from a sockaddr structure?

ntohl. network to host long : convert a 32-bit number from a network representation into the local processor's format. This is commonly used to read an IP address from a sockaddr structure.

What is Sin_family?

sin_family. The address family for the transport address. This member should always be set to AF_INET. sin_port. A transport protocol port number.

What is the data size of the sockaddr structure?

With IPv4 (what basically everyone in 2005 still uses), the struct s_addr is a 4-byte number that represents one digit in an IP address per byte. (You won't ever see an IP address with a number in it greater than 255.)


1 Answers

I would point out that if this is actually C++ the idiomatic way to do this would be:

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.

like image 151
bmatheny Avatar answered Oct 26 '22 12:10

bmatheny