gethostbyname()之后的本地IP

时间:2011-06-27 09:14:29

标签: c sockets network-programming

在使用将用于传输到远程主机的sendto()之前,如何获取本地IP地址?

如果我理解正确,应在gethostbyname(remoteHostname)致电后知道。

我需要这个以便在传输的数据包中包含本地IP(127.0.0.1没有意义)。使用UDP。

3 个答案:

答案 0 :(得分:2)

尝试在连接的UDP套接字上调用getsockname(2);堆栈需要执行相当数量的路由来连接套接字,足以知道在发送或接收数据包后将使用哪个本地地址。

答案 1 :(得分:1)

您可以先在套接字上调用connect()。 UDP ofcourse不是面向连接的,但是connect只是注册套接字只发送到给定的远程IP地址,所以你可以例如只需使用send()而不是sendto()

但是,这允许您在套接字上调用getsockname(),至少在Linux下,这将获取套接字使用的本地地址。这是一个示例,您可以在此处提取print_local_addr()中的信息,并在SNMP陷阱中使用该信息。 (只有在你想要一个固定的源端口时才需要bind()调用)

#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>


void diep(char *s)
{
  perror(s);
  exit(1);
}

void print_local_addr(int s)
{
    struct sockaddr_in my_addr;
    socklen_t len = sizeof my_addr;
    if(getsockname(s,(struct sockaddr*)&my_addr,&len) == -1)
      diep("getsockname");
    //print the local address of the socket that will be used when
    //sending datagrams to the "connected" peer.
    printf("local addr %s:%u\n",inet_ntoa(my_addr.sin_addr),ntohs(my_addr.sin_port));
}

int main(void)
{
  struct sockaddr_in si_me, si_other;
  int s;

  if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
    diep("socket");

  memset(&si_me, 0, sizeof(si_me));
  memset(&si_other, 0, sizeof(si_me));
  //bind to local port 4567
  si_me.sin_family = AF_INET;
  si_me.sin_port = htons(4567);
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);

  //"connect" google's DNS server at 8.8.8.8 , port 4567
  si_other.sin_family = AF_INET;
  si_other.sin_port = htons(4567);
  si_other.sin_addr.s_addr = inet_addr("8.8.8.8");
  if(connect(s,(struct sockaddr*)&si_other,sizeof si_other) == -1)
    diep("connect");
  print_local_addr(s);
  close(s);
  return 0;
}

答案 2 :(得分:0)

信息来自:http://www.suite101.com/content/socket-programming-gethostbyname-a19557

如你所说,localhost不起作用。相反,请先查找您的主机名,然后将其传递给gethostbyname

char hostName[255];
gethostname(hostName, 255);

struct hostent* host_entry;
host_entry=gethostbyname(hostName);

char* localIP;
szLocalIP = inet_ntoa (*(struct in_addr*)*host_entry->h_addr_list);

如果这不合适,您还可以进行DNS查找,执行WMI查询或在注册表中查找。