C语言 如何在C中给客户端特定的IP地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15673846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:51:00  来源:igfitidea点击:

How to give to a client specific ip address in C

csocketsclient-serverip-address

提问by Alex

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:

我正在尝试用 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);

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

在服务器端,我检查客户端 IP 地址,我总是得到 127.0.0.1

I want to change it something different.

我想改变它一些不同的东西。

回答by Adam Rosenfield

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:

如果您希望您的客户端使用特定的网络接口进行连接(例如,因为您有多个网卡),那么您首先需要在调用bind(2)之前调用该接口的 IP 地址connect。例如,如果您有两个 IP 地址分别为 192.168.1.100 和 10.101.151.100 的网络接口,那么要使用 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));

回答by jleslie48

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

好的,所以我将解决方案与从计算机上获取的 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), '##代码##', 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.

我已经在我的 debian linux 嵌入式 arm ts-7500 单板计算机上运行了它。