开发者

How can I obtain the IPv4 address of the client?

开发者 https://www.devze.com 2022-12-23 23:26 出处:网络
I\'m prepping for a simple work project and am trying to familiarize myself with the basics of socket programming in a Unix dev environment.At this point, I have some basic server side code setup to l

I'm prepping for a simple work project and am trying to familiarize myself with the basics of socket programming in a Unix dev environment. At this point, I have some basic server side code setup to listen for incoming TCP connection requests from clients after the parent socket has been created and is set to listen...

int sockfd, newfd;    
unsigned int len;
socklen_t sin_size;
char msg[]="Test message sent";
char buf[MAXLEN];
int st, rv;
struct addrinfo hints, *serverinfo, *p; 
struct sockaddr_storage client;
char ip[INET6_ADDRSTRLEN];

.
. //parent socket creation and listen code omitted for simplicity
.

//wait for connection requests from clients
while(1)
  {
    //Returns the socketID and address of client connecting to socket
    if( ( newfd = accept(sockfd, (struct sockaddr *)&client, &len) ) == -1 ){
      perror("Accept");
      exit(-1);
    }

    if( (rv = recv(newfd, buf, MAXLEN-1, 0 )) == -1) {
      perror("Recv");
      exit(-1);
    }
    struct sockaddr_in *clientAddr = ( struct sockaddr_in *) get_in_addr((struct sockaddr *)&client);
    inet_ntop(client.ss_family, clientAddr, ip, sizeof ip);
    printf("Receive from %s: query type is %s\n", ip, buf);

    if( ( st = send(newfd, msg, st开发者_JS百科rlen(msg), 0)) == -1 ) {
      perror("Send");
      exit(-1);
    }

    //ntohs is used to avoid big-endian and little endian compatibility issues
    printf("Send %d byte to port %d\n", ntohs(clientAddr->sin_port) );

    close(newfd);
  }

}

I found the get_in_addr function online and placed it at the top of my code and use it to obtain the IP address of the client connecting...

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }

  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

but the function always returns the IPv6 IP address since thats what the sa_family property is set as.

My question is, is the IPv4 IP address stored anywhere in the data I'm using and, if so, how can I access it?

Thanks so much in advance for all your help!


If you're getting an IPv6 address, then that's what the client is using to connect. There isn't a 1-1 correspondence between IPv6 and IPv4 addresses, nor between IP addresses and client devices.

Its a bit like saying you've received an email from someone, but you're having trouble working out their postal address from their email address.


See The need for a "getipv4addr" and "getipv6addr" function article on my website. It describes how you can obtain the IPv4 or IPv6 address of the computer on which it is running.


While you are physically getting an IPv6 address, if the client connected with IPv4 then the address will in the IPv4-mapped address format.

You can extract the IPv4 portion of the address by accessing bytes 12, 13, 14 and 15 of s6_addr.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号