How to give to a client specific ip address in C
Asked Answered
H

2

20

I am trying to implement a simple client and server in C and I can't find online an example how to set a specific IP address to the client. This is what I got so far:

sockfd = socket(PF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
    <some code to handle error>
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(<addressOfTheServer>);
address.sin_port = htons(<portToConnectToServer>);
len = sizeof(address);

int result = connect(sockfd, (struct sockaddr *)&address, len);

On the server side I check for the client IP Address and I always get 127.0.0.1

I want to change it something different.

Holtz answered 28/3, 2013 at 3:38 Comment(5)
Use bind() before connect() to set the local address and/or port of the socket. But if the client and server are on different machines, the client address can never be 127.0.0.1.Sulfamerazine
How are you checking the client's adress?Pottage
char *ip = inet_ntoa(client_address.sin_addr); printf("Ip Address -> %s\n", ip);Holtz
You're seeing 127.0.0.1 because you are running your client and server on the same machine. The IP address of your computer is assigned by the router you're connected to. Why do you want a different IP?Floris
I want to test threads, so that each client when connects a separate thread is created, so I need clients with different IP addresses to see what is going onHoltz
M
40

If you want your client to connect using a specific network interface (say, because you have multiple network cards), then you first need to call bind(2) on that interface's IP address before connecting. For example, if you have two network interfaces with IP addresses 192.168.1.100 and 10.101.151.100, then to connect using the 192.168.1.100 address you could do this:

// Error checking omitted for expository purposes
int sockfd = socket(AF_INET, SOCK_STREAM, 0);

// Bind to a specific network interface (and optionally a specific local port)
struct sockaddr_in localaddr;
localaddr.sin_family = AF_INET;
localaddr.sin_addr.s_addr = inet_addr("192.168.1.100");
localaddr.sin_port = 0;  // Any local port will do
bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr));

// Connect to the remote server
struct sockaddr_in remoteaddr;
remoteaddr.sin_family = AF_INET;
remoteaddr.sin_addr.s_addr = inet_addr(server_ip);
remoteaddr.sin_port = htons(server_port);
connect(sockfd, (struct sockaddr *)&remoteaddr, sizeof(remoteaddr));
Megrim answered 28/3, 2013 at 5:23 Comment(3)
What if ethernet and wifi have same network id and address?Sarge
Notice that if I enter a different address when connecting to the remote server, there will be no error - it will just hang as if it is connected to somewhere...Marilyn
What's the difference between this method and passing the interface name via setsockopt ?Slr
S
2

OK so I put the solution together with getting the ip address off of the computer as well:

     /*dl_senderprog.c - debian linux send to server a client, datagram*/

 /***********************************************************************


 140203  lets see if we can bind to a port

 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket# vi senderprog_bind.c
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket# gcc -g senderprog_bind.c -o senderprog_bind
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind
 Sender:Client-Usage: ./senderprog_bind <hostname> <message>
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket# ./senderprog_bind 10.0.1.26 "dot,33,22"
 MY IP address:10.0.1.242: on port: 1043
 Sender: Client-gethostname() is OK...
 Sender: Client-socket() sockfd is OK...
 Sender: Using port: 14950
 Sender: Client-sendto() is OK...
 Sender: sent 9 bytes to 10.0.1.26
 Sender: Client-sockfd successfully closed!
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket# # it worked!!!!!
 ts7500:/var/www/jon/uvir_sensor_lab/source/socket#



 ***********************************************************************/




 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>

 #include <sys/ioctl.h>
 #include <net/if.h>





 /* the port users will be connecting to 14950 is the port on the windows machine
    that I have the server running on */
 #define TOPORT 14950
 #define MYPORT 1043

 void my_ip( char *myniccard, char *myipaddr) {
      int fd;
      struct ifreq ifr;

      myipaddr[0]=0;

      fd = socket(AF_INET, SOCK_DGRAM, 0);

      /* I want to get an IPv4 IP address */
      ifr.ifr_addr.sa_family = AF_INET;

      /* I want IP address attached to "eth0" */
      //strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
      strncpy(ifr.ifr_name, myniccard, IFNAMSIZ-1);

      ioctl(fd, SIOCGIFADDR, &ifr);

      close(fd);

      /* display result */
      sprintf(myipaddr,"%s"
        , inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
      printf("MY IP address:%s: on port: %d\n", myipaddr, MYPORT);

      }   // my_ip


 int main(int argc, char *argv[ ])
 {
 int sockfd;
 /* connectors address information */
 struct sockaddr_in their_addr;
 struct sockaddr_in localaddr;
 char myipaddressm[22];   //buffer for ip address
 char *myniccardm ="eth0";   // check with ipconfig for correct ethernet port

 struct hostent *he;
 int numbytes;

 if (argc != 3) {
      fprintf(stderr, "Sender:Client-Usage: %s <hostname> <message>\n", argv[0]);
      exit(1);
      }

 my_ip(myniccardm, myipaddressm);


 /* get the host info */
 if ((he = gethostbyname(argv[1])) == NULL) {
      perror("Sender: Client-gethostbyname() error lol!");
      exit(1);
      }
  else
      printf("Sender: Client-gethostname() is OK...\n");

 if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
       perror("Sender: Client-socket() error lol!");
       exit(1);
       }
   else
       printf("Sender: Client-socket() sockfd is OK...\n");


 // Bind to a specific network interface
 // (this is unusual, as you normally do not want a specific
 //  port for the client, but we have a specific server in
 //  this case that will not accept connects unless its on
 //  a specific port )
 localaddr.sin_family = AF_INET;
 localaddr.sin_addr.s_addr = inet_addr(myipaddressm);
 localaddr.sin_port = htons(MYPORT);  // Any local port will do
 bind(sockfd, (struct sockaddr *)&localaddr, sizeof(localaddr));



 /* host byte order */
 their_addr.sin_family = AF_INET;
 /* short, network byte order */
 printf("Sender: Using port: %d\n",TOPORT);
 their_addr.sin_port = htons(TOPORT);
 their_addr.sin_addr = *((struct in_addr *)he->h_addr);
 /* zero the rest of the struct */
 memset(&(their_addr.sin_zero), '\0', 8);

 if((numbytes = sendto(sockfd, argv[2],
                       strlen(argv[2]),
                       0,
                       (struct sockaddr *)&their_addr,
                       sizeof(struct sockaddr))) == -1) {
       perror("Sender: Client-sendto() error lol!");
       exit(1);
       }
   else
       printf("Sender: Client-sendto() is OK...\n");

 printf("Sender: sent %d bytes to %s\n", numbytes, inet_ntoa(their_addr.sin_addr));

 if (close(sockfd) != 0)
       printf("Sender: Client-sockfd closing is failed!\n");
   else
       printf("Sender: Client-sockfd successfully closed!\n");
 return 0;

 }//main


 /*******************************************EOF***********************/

I've run this on my debian linux embedded arm ts-7500 single board computer.

Seleneselenious answered 4/2, 2014 at 16:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.