12

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

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

4

2 回答 2

32

如果您希望您的客户端使用特定的网络接口进行连接(例如,因为您有多个网卡),那么您首先需要在ingbind(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));
于 2013-03-28T05:23:39.840 回答
2

好的,所以我将解决方案与从计算机上获取 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 嵌入式 arm ts-7500 单板计算机上运行了它。

于 2014-02-04T16:02:07.237 回答