web-dev-qa-db-ja.com

Cでクライアント固有のIPアドレスを与える方法

Cで単純なクライアントとサーバーを実装しようとしていますが、クライアントに特定のIPアドレスを設定する方法の例がオンラインで見つかりません。これは私がこれまでに得たものです:

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);

サーバー側でクライアントのIPアドレスを確認し、常に127.0.0.1を取得します

違うものに変えたいです。

7
Alex

クライアントが特定のネットワークインターフェイスを使用して接続するようにする場合(たとえば、複数のネットワークカードがあるため)、まずconnectingの前にそのインターフェイスのIPアドレスで bind(2) を呼び出す必要があります。たとえば、IPアドレスが192.168.1.100と10.101.151.100の2つのネットワークインターフェースがある場合、192.168.1.100アドレスを使用して接続するには、次のようにします。

// 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));
21
Adam Rosenfield

わかりましたので、コンピューターからIPアドレスを取得することと一緒にソリューションを配置します。

     /*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***********************/

私はこれを私のdebian linux組み込みアームts-7500シングルボードコンピューターで実行しました。

1
jleslie48