LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3717|回复: 9

Linux下面的socket编程,如何获得本机IP地址啊????

[复制链接]
发表于 2005-10-11 15:30:25 | 显示全部楼层 |阅读模式
Linux下面的socket编程,如何获得本机IP地址啊?
也就是说显示自己的IP要用socket编程来实现.用C语言.
哪位大侠知道告诉我一下!
发表于 2005-10-11 16:12:40 | 显示全部楼层
getsockname
回复 支持 反对

使用道具 举报

发表于 2005-10-12 17:29:48 | 显示全部楼层
经典问题啊. 到GOOGLE一找便知.
我手中有一个KYLIX版的. 你可以参考一下, 主要是用IOCTL 函数

  1. uses Libc;
  2. function GetIP(Index: Integer): string;
  3. var
  4.   ifr: Libc.ifreq;
  5.   sockfd: Integer;
  6. begin
  7.   FillChar(ifr, sizeof(ifr),#0);
  8.   sockfd := Libc.socket(Libc.AF_INET, SOCK_STREAM, 0);
  9.   if sockfd < 0 then
  10.     raise Exception.Create('Socket open error.');
  11.   StrPCopy(ifr.ifrn_name, 'eth' + IntToStr(Index));
  12.   ifr.ifru_addr.sin_family := Libc.AF_INET;

  13.   if Libc.ioctl(sockfd, Libc.SIOCGIFADDR, @ifr) = 0 then
  14.   begin
  15.     Result := Libc.inet_ntoa(ifr.ifru_addr.sin_addr);
  16.   end
  17.   else
  18.     raise Exception.Create('get ip error.');
  19. end;

复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-10-12 22:02:21 | 显示全部楼层
在google上面搜出来的都是这样的:
struct sinaddr_in server;
server.sin_addr=htonl(INADDR_ANY);
这样来得到自身IP地址.
可是我这样得到的IP是127.0.0.1而不是我本身在使用的IP这是怎么回事???
回复 支持 反对

使用道具 举报

发表于 2005-10-12 23:34:41 | 显示全部楼层
送你一段

  1. #include <string.h>
  2. #include <sys/socket.h>
  3. #include <sys/ioctl.h>
  4. #include <net/if.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main()
  9. {
  10.         int inet_sock;
  11.         struct ifreq ifr;

  12.         inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
  13.         strcpy(ifr.ifr_name, "eth0");
  14.         if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
  15.                 perror("ioctl");
  16.         printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));

  17.         return 0;
  18. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-10-31 16:21:24 | 显示全部楼层
如果网卡不止一块,还可以用ioctl还做吗?
怎么知道网卡的数量呢?

Post by 小锁
送你一段

  1. #include <string.h>
  2. #include <sys/socket.h>
  3. #include <sys/ioctl.h>
  4. #include <net/if.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main()
  9. {
  10.         int inet_sock;
  11.         struct ifreq ifr;

  12.         inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
  13.         strcpy(ifr.ifr_name, "eth0");
  14.         if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
  15.                 perror("ioctl");
  16.         printf("%s\n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));

  17.         return 0;
  18. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-10-31 18:38:52 | 显示全部楼层

  1. #include <string.h>
  2. #include <sys/socket.h>
  3. #include <sys/ioctl.h>
  4. #include <net/if.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main()
  9. {
  10.         int inet_sock;
  11.         struct ifreq ifr;
  12.         FILE *net_devs;
  13.         char buf[1024];
  14.         char interface[32];

  15.         net_devs = fopen("/proc/net/dev", "r");
  16.         if(net_devs == NULL){
  17.                 perror("Can't open /proc/net/dev for reading");
  18.                 exit(1);
  19.         }

  20.         inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
  21.         while(1){
  22.                 if(fscanf(net_devs, "%32s %1024[^\n]", interface, buf) <= 0){
  23.                         break;
  24.                 }
  25.                 if(interface[strlen(interface) - 1] != ':'){
  26.                         continue; // skip the comment
  27.                 }else{
  28.                         interface[strlen(interface) - 1] = '\0';
  29.                 }
  30.                 strcpy(ifr.ifr_name, interface);
  31.                 if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
  32.                         perror("ioctl");
  33.                 printf("%s:%s\n", interface,
  34.                                 inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
  35.         }
  36.         close(inet_sock);

  37.         return 0;
  38. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-11-1 15:42:48 | 显示全部楼层
对流量为0的网络接口有用,比如一般的lo;如果流量不是0,就得不到了,比如一般流量不为0的eth0,还有以下的这个(/proc/net/dev):

  1. Inter-|   Receive                                                |  Transmit
  2. face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  3.     lo: 1258287   30893    0    0    0     0          0         0  1258287   30893    0    0    0     0       0          0
  4.   eth0:2584406784 25700762 1909    8    0  1909          0         0   442441    6369    0    0    0     0       0          0
  5.   eth1:4288480977 81743660    0    0    0     0          0         0 1674397726 50377395    0    0    0     0       0          0
  6.   sit0:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
复制代码


试改如下,好像可以得到需要的结果:

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <sys/ioctl.h>
  6. #include <net/if.h>
  7. #include <arpa/inet.h>

  8. int main()
  9. {
  10.         int inet_sock;
  11.         struct ifreq ifr;
  12.         FILE *net_devs;
  13.         char buf[1024];
  14.         char interface[32];
  15.         int index;

  16.         net_devs = fopen("/proc/net/dev", "r");
  17.         if(net_devs == NULL){
  18.                 perror("Can't open /proc/net/dev for reading");
  19.                 exit(1);
  20.         }

  21.         inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
  22.         while(1){
  23.                 if(fscanf(net_devs, "%32s %1024[^\n]", interface, buf) <= 0){
  24.                         break;
  25.                 }
  26.                 index = 0;
  27.                 while ( index<32 && interface[index] != ':' ) {
  28.                         index++;
  29.                 }
  30.                 if (index>=32)
  31.                         continue;
  32.                 interface[index] = '\0';
  33.                 strcpy(ifr.ifr_name, interface);
  34.                 if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
  35.                         perror("ioctl");
  36.                 printf("%s:\t%s\n", interface,
  37.                                 inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
  38.         }
  39.         close(inet_sock);



  40.         return 0;
  41. }
复制代码

对了,那个buf是做什么的?没有看出来。


Post by 小锁

  1. #include <string.h>
  2. #include <sys/socket.h>
  3. #include <sys/ioctl.h>
  4. #include <net/if.h>
  5. #include <stdio.h>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>

  8. int main()
  9. {
  10.         int inet_sock;
  11.         struct ifreq ifr;
  12.         FILE *net_devs;
  13.         char buf[1024];
  14.         char interface[32];
  15.         ...
  16.         ...

  17. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2005-11-2 10:16:33 | 显示全部楼层
觉得还是getsockname(int sockfd,struct sockaddr *localaddr,socklen_t *addrlen) 来得比较简单,何必弄得那么复杂呢
回复 支持 反对

使用道具 举报

发表于 2005-11-2 12:15:26 | 显示全部楼层
buf只是用来放后续内容,没什么用。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表