c++ 获取本地ip地址
最终版本:采用指针传参数,不使用别名形式。
#include <unistd.h>
#include <netdb.h> //gethostbyname
#include <arpa/inet.h> //ntohl
#include <iostream>
using namespace std; int get_local_ip(int *ip) {
char hostname[];
int ret = gethostname(hostname, sizeof(hostname));
if (ret == -){
return -;
}
struct hostent *hent;
hent = gethostbyname(hostname);
if (NULL == hent) {
return -;
}
//直接取h_addr_list列表中的第一个地址h_addr
*ip = ntohl(((struct in_addr*)hent->h_addr)->s_addr);
//int i;
//for(i=0; hent->h_addr_list[i]; i++) {
// uint32_t u = ntohl(((struct in_addr*)hent->h_addr_list[i])->s_addr);
// std::cout << u << std::endl;
//}
return ;
} int main() { //10.94.45.25
//unsigned long ii = 0l; //ii |= 25;
//ii |= 45 << 8;
//ii |= 94 << 16;
//ii |= 10 << 24; //cout << ii << endl; int ip = ;
int ret = get_local_ip(&ip);
if (ret == ) {
cout << ip << endl;
} else {
cerr << "wrong" << endl;
}
return ;
} /* vim: set ts=4 sw=4 sts=4 tw=100 */
/*最终定稿*/ #include <unistd.h>
#include <netdb.h> //gethostbyname
#include <arpa/inet.h> //ntohl
#include <iostream>
using namespace std; int get_local_ip(int& ip) {
char hostname[];
int ret = gethostname(hostname, sizeof(hostname));
if (ret == -){
return -;
}
struct hostent *hent;
hent = gethostbyname(hostname);
if (NULL == hent) {
return -;
}
//直接取h_addr_list列表中的第一个地址h_addr
ip = ntohl(((struct in_addr*)hent->h_addr)->s_addr);
//int i;
//for(i=0; hent->h_addr_list[i]; i++) {
// uint32_t u = ntohl(((struct in_addr*)hent->h_addr_list[i])->s_addr);
// std::cout << u << std::endl;
//}
return ;
} int main() { //10.94.45.25
//unsigned long ii = 0l; //ii |= 25;
//ii |= 45 << 8;
//ii |= 94 << 16;
//ii |= 10 << 24; //cout << ii << endl; int ip;
int ret = get_local_ip(ip);
if (ret == ) {
cout << ip << endl;
} else {
cerr << "wrong" << endl;
}
return ;
}
c ip地址知识点:
struct sockaddr {
unsigned short sa_family;
char sa_data[];
};
sockaddr_in详解
sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表地址组
sa_data是14字节协议地址。
sockaddr 是通用的socket地址,具体到Internet socket,用下面的结构,二者可以进行类型转换
struct sockaddr_in {
short int sin_family; // Address family 一般来说 AF_INET(地址族)PF_INET(协议族 )
unsigned short int sin_port; //sin_port存储端口号(使用网络字节顺序),在linux下,端口号的范围0~65535,同时0~1024范围的端口号已经被系统使用或保留
struct in_addr sin_addr; //存储IP地址
unsigned char sin_zero[]; //sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节
};
struct in_addr就是32位IP地址。
struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr; //s_addr按照网络字节顺序存储IP地址
} S_un;
#define s_addr S_un.S_addr
};
在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺序的问题。这是就可能用到htons(), ntohl(), ntohs(),htons()这4个函数。
网络字节顺序与本地字节顺序之间的转换函数:
#include <arpa/inet.h>
htonl()--"Host to Network Long"
ntohl()--"Network to Host Long"
htons()--"Host to Network Short"
ntohs()--"Network to Host Short" 之所以需要这些函数是因为计算机数据表示存在两种字节顺序:NBO与HBO 网络字节顺序NBO(Network Byte Order): 按从高到低的顺序存储,在网络上使用统一的网络字节顺序,可以避免兼容性问题。 主机字节顺序(HBO,Host Byte Order): 不同的机器HBO不相同,与CPU设计有关,数据的顺序是由cpu决定的,而与操作系统无关。
如 Intel x86结构下, short型数0x1234表示为34 , int型数0x12345678表示为78
如 IBM power PC结构下, short型数0x1234表示为12 , int型数0x12345678表示为12 由于这个原因不同体系结构的机器之间无法通信,所以要转换成一种约定的数序,也就是网络字节顺序,其实就是如同power pc那样的顺序.
在PC开发中有ntohl和htonl函数可以用来进行网络字节和主机字节的转换.
这个数据结构是这样的:
struct hostent {
char *h_name;
char **h_aliases;
int h_addrtype;
int h_length;
char **h_addr_list;
};
#define h_addr h_addr_list[0]
这里是这个数据结构的详细资料:
struct hostent:
h_name – 地址的正式名称。
h_aliases – 空字节-地址的预备名称的指针。
h_addrtype –地址类型; 通常是AF_INET。
h_length – 地址的比特长度。
h_addr_list – 零字节-主机网络地址指针。网络字节顺序。
h_addr - h_addr_list中的第一地址。
gethostbyname() 成功时返回一个指向结构体 hostent 的指针,或者 是个空 (NULL) 指针。(但是和以前不同,不设置errno,h_errno 设置错 误信息。请看下面的 herror()。) 但是如何使用呢? 这个函数可不象它看上去那么难用。
这里是个例子:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct hostent *h;
if (argc != ) { /* 检查命令行 */
fprintf(stderr,"usage: getip address\n");
exit();
}
if ((h=gethostbyname(argv[])) == NULL) { /* 取得地址信息 */
herror("gethostbyname");
exit();
}
printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));
return ;
}
在使用 gethostbyname() 的时候,你不能用perror() 打印错误信息 (因为 errno 没有使用),你应该调用 herror()。
相当简单,你只是传递一个保存机器名的字符串(例如 "whitehouse.gov") 给gethostbyname(),然后从返回的数据结构 struct hostent 中获取信息。 唯一也许让人不解的是输出 IP 地址信息。h->h_addr 是一个 char *,
但是 inet_ntoa() 需要的是 struct in_addr。因此,我转换 h->h_addr 成 struct in_addr *,然后得到数据。
============================================================
参考地址:http://blog.csdn.net/liuqinstudy/article/details/8813932
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netdb.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <iostream>
using namespace std;
int get_local_ip(unsigned long& ip)
{
int sfd, intr;
struct ifreq buf[];
struct ifconf ifc;
sfd = socket(AF_INET, SOCK_DGRAM, );
if (sfd < )
return -;
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = (caddr_t)buf;
if (ioctl(sfd, SIOCGIFCONF, (char *)&ifc))
return -;
intr = ifc.ifc_len / sizeof(struct ifreq);
while (intr-- > && ioctl(sfd, SIOCGIFADDR, (char *)&buf[intr]));
close(sfd);
ip = ntohl(((struct sockaddr_in*)(&buf[intr].ifr_addr))->sin_addr.s_addr);
return ;
} int main() {
unsigned long ip = ;
int ret = get_local_ip(ip);
if (ret == ) {
cout << ip << endl;
} else {
cout << "err" << endl;
}
return ;
}
c++ 获取本地ip地址的更多相关文章
- 获取本地IP地址信息
2012-06-05 /// <summary> /// 获取本地IP地址信息 /// </summary> void G ...
- C# — 动态获取本地IP地址及可用端口
1.在VS中动态获取本地IP地址,代码如下: 2.获取本机的可用端口以及已使用的端口:
- .net获取本地ip地址
整理代码,.net获取本地ip地址,代码如下: string name = Dns.GetHostName(); IPHostEntry IpEntry = Dns.GetHostEntry(name ...
- 获取本地IP地址的vc代码
作者:朱金灿 来源:http://blog.csdn.net/clever101 获取本地IP地址有两种做法.一种是使用gethostname函数,代码如下: bool CSocketComm::Ge ...
- Linux C 网络编程 - 获取本地 ip 地址,mac,通过域名获取对应的 ip
获取本地 ip 地址,mac,通过域名获取对应的 ip, 是网络编程可能遇到的比较常见的操作了,所以总结如下(封装了3个函数), 直接上代码: #include <stdio.h> #in ...
- 获取本地ip地址 C#
与ipconfig获取的所有信息一致的方法: private void GetIp() { System.Diagnostics.Process cmdp= new System.Diagnostic ...
- Linux下编程获取本地IP地址的常见方法
转载于:http://blog.csdn.net/k346k346/article/details/48231933 在进行linux网络编程时,经常用到本机IP地址.本文罗列一下常见方法,以备不时之 ...
- .net core获取本地Ip地址的方法
笔记: /// <summary> /// 获取本地Ip地址 /// </summary> /// <returns></returns> public ...
- Java获取本地IP地址
import java.net.InetAddress; import java.net.UnknownHostException; public class IpTest { public stat ...
- python获取本地ip地址的方法
#_*_coding:utf8_*_ #以下两种方法可以在ubuntu下或者windows下获得本地的IP地址 import socket # 方法一 localIP = socket.gethost ...
随机推荐
- Part 2 How are the URL's mapped to Controller Action Methods?
Part 2 How are the URL's mapped to Controller Action Methods? The answer is ASP.NET Routing.Notice t ...
- nodemanager启动失败
yarn启动报错: 2016-11-16 16:12:44,304 INFO org.apache.hadoop.metrics2.impl.MetricsSystemImpl: Stopping N ...
- Java之简单图形面积计算
设计一个类层次,定义一个抽象类--形状(类名:shape).其中包括求形状的面积抽象方法(方法名:calArea()).继承该抽象类定义三角形(Triangle).矩形(Rectangle).圆(Ci ...
- 浅谈sqlserver数据库优化(一)----开光篇
今天暂时无事,风和日丽,万里无云.游山的.玩水的.遛麻雀的都闲的不亦乐乎,也忙的不亦乐乎.在这美好的季节,依旧躲在被窝或是电脑旁绞尽脑汁敲键盘的人们,也别有一番滋味.废话少说,言归正传. 赶上了一个最 ...
- iOS-设置启动图片
启动图片设置 设置方法一 这种方法里,默认模拟器和真机的尺寸和启动图片的尺寸相同. 通过美工提供各种尺寸的启动图片来适配屏幕的大小.这种方法要求美工提供各种屏幕大小的图片. 步骤如下: 1.如图所示, ...
- MATLAB 生成 COM 步骤
环境: 操作系统:windows xp sp3 MATLAB:Version 7.1.0.246(R14) Service Pack 3 第一步:安装编译器(如果已经安装则可跳过此步) 在MATLAB ...
- 正确的安装和使用nvm
前言 目前主流的node版本管理工具有两种,nvm和n.两者差异挺大的,具体分析可以参考一下淘宝FED团队的一篇文章: 管理 node 版本,选择 nvm 还是 n? 总的来说,nvm有点类似于 Py ...
- ArcGIS 坐标系统文件
坐标是GIS数据的骨骼框架,能够将我们的数据定位到相应的位置,为地图中的每一点提供准确的坐标. ArcGIS自带了多种坐标系统,在${ArcGISHome}Coordinate Systems目录下可 ...
- CC2530之Flash映射
标准51系列内核的逻辑空间为哈佛结构,也就是说,程序空间和地址空间是分开的.具体分为: CODE区:存放程序代码和一些常量信息,有16根地址总线,寻址范围为0x0000~0xFFFF,共计64K DA ...
- mobileconfig文件的签名和认证(signed、verified)
专题:基于IOS上MDM技术相关资料整理及汇总mobileconfig文件的签名和认证(signed.verified) 一.功能描述: 鉴于我们的设备和MDM server之间已经可以通信,并能完成 ...