您的位置:首页 > 运维架构 > Linux

Jeremiah的小程序之一:Linux下获取本机的IP地址

2010-02-09 21:04 447 查看
请移步https://higoge.github.io/,所有下载资料在那个博客都能找到。谢谢。 -------------------------------------------------------------------- 从这篇博客开始,Jeremiah将会把自己平常写的些简单的小程序或者平常读的开源代码中比较好的做法和应用整理下来。

本篇博客主要是抠取自live555MediaServer,在开启live555MediaServer的时候会读取本地IP,然后与rtsp://和文件名组成点播地址。live555MediaServer读取本地IP的主要方法是:发送一个TTL=0的组播包,接收这个包,然后解析发送地址,即为本机地址。

这种方法只能获得本机的最主要的IP地址(eth0)。不能获取所有的IP地址。

抠取代码如下,操作平台为RedHat Linux ES5,gcc 4.1.2。
/*******************************************************************************   * Filename:        get_ip.c   * Created on:      Feb 8, 2010   * Author:          Jeremiah   * Description:     获取本机IP地址   *   ******************************************************************************/  #include <stdio.h>  #include <stdint.h>  #include <stdlib.h>  #include <unistd.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h>  #include <string.h>  #include <sys/time.h>  #include <sys/select.h>   in_addr_t ourIPAddress();  int setupDatagramSocket(uint16_t);  uint8_t socketJoinGroup(int socket, uint32_t groupAddress);  uint8_t writeSocket(int socket, struct in_addr address, uint32_t port,          uint8_t ttlArg, unsigned char *buffer, unsigned bufferSize);  int readSocket(int socket, unsigned char *buffer, unsigned bufferSize,          struct sockaddr_in *fromAddress, struct timeval *timeout);  int blockUntilReadable(int socket, struct timeval* timeout);  uint8_t badAddress(uint32_t addr);  uint8_t socketLeaveGroup(int socket, uint32_t groupAddress);  uint8_t IsMulticastAddress(uint32_t address);   #define SET_SOCKADDR_SIN_LEN(var)  #define MAKE_SOCKADDR_IN(var,adr,prt) /*adr,prt must be in network order*/\      struct sockaddr_in var;\      var.sin_family = AF_INET;\      var.sin_addr.s_addr = (adr);\      var.sin_port = (prt);\      SET_SOCKADDR_SIN_LEN(var);   int main(int argc, char **argv) {      struct sockaddr_in ourAddress;      ourAddress.sin_addr.s_addr = ourIPAddress();       if (ourAddress.sin_addr.s_addr == 0) {          printf("get local ip error!\n");          return 1;      }       printf("%s\n", inet_ntoa(ourAddress.sin_addr));       return 0;  }   in_addr_t ourIPAddress() {      uint32_t ourAddress = 0;      int sock = -1;      struct in_addr testAddr;      struct sockaddr_in fromAddr;      fromAddr.sin_addr.s_addr = 0;       // Get our address by sending a (0-TTL) multicast packet,      // receiving it, and looking at the source address used.      // (This is kinda bogus, but it provides the best guarantee      // that other nodes will think our address is the same as we do.)      testAddr.s_addr = inet_addr("228.67.43.92");      uint16_t testPort = 15948;      sock = setupDatagramSocket(testPort);      if (sock < 0) {          return 0;      }       if (!socketJoinGroup(sock, testAddr.s_addr)) {          return 0;      }       unsigned char testString[] = "hostIdTest";      unsigned testStrLength = sizeof(testString);      if (!writeSocket(sock, testAddr, testPort, 0, testString, testStrLength)) {          return 0;      }       unsigned char readBuffer[20];      struct timeval timeout;      timeout.tv_sec = 5;      timeout.tv_usec = 0;       int bytesRead = readSocket(sock, readBuffer, sizeof(readBuffer), &fromAddr,              &timeout);      if (bytesRead == 0 // timeout occurred              || bytesRead != (int) testStrLength || strncmp(              (char *) readBuffer, (char *) testString, testStrLength) != 0) {          printf("read socket error\n");          return 0;      }       uint32_t from = fromAddr.sin_addr.s_addr;      if (badAddress(from)) {          printf("This computer has an invalid IP address: 0x%x\n",                  (uint32_t) (ntohl(from)));          from = 0;      }       ourAddress = from;       if (sock >= 0) {          socketLeaveGroup(sock, testAddr.s_addr);          close(sock);      }       return ourAddress;  }   int setupDatagramSocket(uint16_t port) {      int reuseFlag = 1;      int newSocket = socket(AF_INET, SOCK_DGRAM, 0);      const uint8_t loop = 1;       if (newSocket < 0) {          printf("unable to create datagram socket\n");          return newSocket;      }       if (setsockopt(newSocket, SOL_SOCKET, SO_REUSEADDR,              (const char *) &reuseFlag, sizeof(reuseFlag)) < 0) {          printf("setsockopt(SO_REUSEADDR) error!\n");          close(newSocket);          return -1;      }       if (setsockopt(newSocket, IPPROTO_IP, IP_MULTICAST_LOOP,              (const char*) &loop, sizeof(loop)) < 0) {          printf("setsockopt(IP_MULTICAST_LOOP) error!\n");          close(newSocket);          return -1;      }       uint32_t addr = INADDR_ANY;      MAKE_SOCKADDR_IN(name, addr, port);       if (bind(newSocket, (struct sockaddr *) &name, sizeof(name)) != 0) {          printf("bind() error (port number: %d)!\n", ntohs(port));          close(newSocket);          return -1;      }       return newSocket;  }   uint8_t socketJoinGroup(int socket, uint32_t groupAddress) {      if (!IsMulticastAddress(groupAddress)) {          return 1; // ignore this case      }       struct ip_mreq imr;      imr.imr_multiaddr.s_addr = groupAddress;      imr.imr_interface.s_addr = INADDR_ANY;      if (setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *) &imr,              sizeof(struct ip_mreq)) < 0) {          printf("setsockopt(IP_ADD_MEMBERSHIP) error!\n");          return 0;      }       return 1;  }    uint8_t writeSocket(int socket, struct in_addr address, uint32_t port,          uint8_t ttlArg, unsigned char *buffer, unsigned bufferSize) {      if (ttlArg != 0) {          // Before sending, set the socket's TTL:          uint8_t ttl = ttlArg;          if (setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL,                  (const char *) &ttl, sizeof(ttl)) < 0) {              printf("setsockopt(IP_MULTICAST_TTL) error!");              return 0;          }      }      MAKE_SOCKADDR_IN(dest, address.s_addr, port);      int bytesSent = sendto(socket, (char *) buffer, bufferSize, 0,              (struct sockaddr *) &dest, sizeof(dest));      if (bytesSent != (int) bufferSize) {          printf("writeSocket(%d), sendTo() error: wrote "                 "%d bytes instead of %u!\n", socket, bytesSent, bufferSize);          return 0;      }       return 1;  }   int readSocket(int socket, unsigned char *buffer, unsigned int bufferSize,          struct sockaddr_in *fromAddress, struct timeval *timeout) {      int bytesRead = -1;       int result = blockUntilReadable(socket, timeout);      if (timeout != NULL && result == 0) {          bytesRead = 0;          return -1;      } else if (result <= 0) {          return -1;      }       socklen_t addressSize = (socklen_t) sizeof(struct sockaddr_in);      bytesRead = recvfrom(socket, (char *) buffer, bufferSize, 0,              (struct sockaddr *) fromAddress, &addressSize);      if (bytesRead < 0) {          printf("recvfrom() error!\n");          return -1;      }       return bytesRead;  }   int blockUntilReadable(int socket, struct timeval *timeout) {      int result = -1;      fd_set rd_set;      FD_ZERO(&rd_set);      if (socket < 0)          return -1;      FD_SET((unsigned) socket, &rd_set);      const unsigned numFds = socket + 1;       result = select(numFds, &rd_set, NULL, NULL, timeout);      if (timeout != NULL && result == 0) {          printf("select timeout!\n");          return -1; // this is OK - timeout occurred      } else if (result <= 0) {          printf("select() error!\n");          return -1;      }       if (!FD_ISSET(socket, &rd_set)) {          printf("select() error - !FD_ISSET!\n");          return -1;      }       return result;  }   uint8_t badAddress(uint32_t addr) {      // Check for some possible erroneous addresses:      uint32_t hAddr = ntohl(addr);      return (hAddr == 0x7F000001 /* 127.0.0.1 */     || hAddr == 0 || hAddr == (uint32_t) (~0));  }   uint8_t socketLeaveGroup(int socket, uint32_t groupAddress) {      if (!IsMulticastAddress(groupAddress))          return 1; // ignore this case       struct ip_mreq imr;      imr.imr_multiaddr.s_addr = groupAddress;      imr.imr_interface.s_addr = INADDR_ANY;      if (setsockopt(socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const char *) &imr,              sizeof(struct ip_mreq)) < 0) {          return 0;      }       return 1;  }   uint8_t IsMulticastAddress(uint32_t address) {      // Note: We return False for addresses in the range 224.0.0.0      // through 224.0.0.255, because these are non-routable      // Note: IPv4-specific #####      uint32_t addressInHostOrder = ntohl(address);      return addressInHostOrder > 0xE00000FF && addressInHostOrder <= 0xEFFFFFFF;  }

本文出自 “海狗哥的流媒体空间” 博客,请务必保留此出处http://jeremiah.blog.51cto.com/539865/275791
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: