在使用将用于传输到远程主机的sendto()
之前,如何获取本地IP地址?
如果我理解正确,应在gethostbyname(remoteHostname)
致电后知道。
我需要这个以便在传输的数据包中包含本地IP(127.0.0.1没有意义)。使用UDP。
答案 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查询或在注册表中查找。