尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

Linux下MyIpAdd库的使用

Linux下MyIpAdd库的使用
📅 发布时间:2026/7/22 23:35:39

一、MyIpAdd库简介

MyIpAdd库是一个纯C++库,可以用它获取我们的公网IP地址。其github地址为:https://github.com/felmur/MyIpAdd

二、下载编译MyIpAdd源码

从 https://github.com/felmur/MyIpAdd 下载MyIpAdd源码:

解压,进入源码目录,可以看到其目录结构如下:

编译:

cmake . -DCMAKE_INSTALL_PREFIX=$(pwd)/install make make install

然后源码目录下会生成MyIpAdd的库文件libMyIpAdd.so:

三、MyIpAdd的使用例子

以C++为例,编写一个使用示例。main.cpp内容如下:

#include <iostream> #include <myipadd.h> using namespace std; int main() { MyIpAdd * m = new MyIpAdd(); cout << "My public ip address is: '" << m->ip << "'" << endl; return 0; }

编译:

g++ main.cpp -o main -g -IXXX/MyIpAdd-master -LXXX/MyIpAdd-master -lMyIpAdd

运行,效果如下。可以看到本机的公网ip被成功打印出来了:

该ip和通过百度查询到的公网ip一致:

四、MyIpAdd源码里的bug

MyIpAdd源码里,myipadd.cpp的构造函数 MyIpAdd::MyIpAdd()的代码为:

MyIpAdd::MyIpAdd() { buf = static_cast<char *>(malloc(1024)); sk = socket(AF_INET, SOCK_STREAM, 0); if (sk==0) { if (DEBUG) cout << "Socket error" << endl; exit(-1); } if (DEBUG) cout << "Socket creation OK" << endl; host = gethostbyname(addr.c_str()); if (host == nullptr ) { if (DEBUG) cout << "Bad host '" << addr << "'" << endl; exit(-3); } addrin.sin_family = AF_INET; addrin.sin_port = htons(80); addrin.sin_addr.s_addr = *(reinterpret_cast<unsigned int*>(host->h_addr)); if (connect(sk, reinterpret_cast<struct sockaddr *>(&addrin), sizeof(addrin))<0){ if (DEBUG) cout << "Connection Failed" << endl; exit(-2); } if (DEBUG) cout << "Connection OK" << endl; string msg = "GET / HTTP/1.1\r\nHost: " + addr + "\r\nConnection: close\r\n\r\n"; send(sk, msg.c_str(), msg.length(), 0); ssize_t ret = 0; string html; while((ret = read( sk , buf, sizeof(buf)))>0) { *(buf+ret) = 0; html += buf; } list<string> cont; split(html,cont,'\n'); size_t r = 0; for(auto& line : cont) { if (line.length()>20) { if ((r = line.find("Current IP Address:"))!=string::npos) { string a = line.substr(r+20); a = a.substr(0,a.find("<")); if (DEBUG) cout << a << endl; ip = a; } } } close(sk); }

可以看到里面调用了exit函数:

host = gethostbyname(addr.c_str()); if (host == nullptr ) { if (DEBUG) cout << "Bad host '" << addr << "'" << endl; exit(-3); }

也就是说,当解析默认域名:checkip.dyndns.com 失败时,MyIpAdd 构造函数会直接 exit(-3),从而把整个调用MyIpAdd函数的进程退出。MyIpAdd 构造函数会把DNS/socket/connect失败当成致命错误,直接退出整个进程。

五、修复MyIpAdd源码里的退出bug

修改 MyIpAdd 源码,把MyIpAdd::MyIpAdd() 里的 exit(...) 改成“失败但不退出进程”的形式,然后重新编译 libMyIpAdd.so,就能解决调用MyIpAdd的进程退出问题。

比如修改为:

if (host == nullptr) { ip = ""; return; }

或者更完整一点:

if (host == nullptr) { if (buf) free(buf); if (sk > 0) close(sk); ip = ""; return; }

修复后,整个MyIpAdd::MyIpAdd()函数改为:

MyIpAdd::MyIpAdd() { sk = socket(AF_INET, SOCK_STREAM, 0); if (sk < 0) { if (DEBUG) cout << "Socket error" << endl; return; } if (DEBUG) cout << "Socket creation OK" << endl; host = gethostbyname(addr.c_str()); if (host == nullptr || host->h_addr == nullptr) { if (DEBUG) cout << "Bad host '" << addr << "'" << endl; close(sk); sk = -1; return; } addrin.sin_family = AF_INET; addrin.sin_port = htons(80); addrin.sin_addr.s_addr = *(reinterpret_cast<unsigned int*>(host->h_addr)); if (connect(sk, reinterpret_cast<struct sockaddr *>(&addrin), sizeof(addrin))<0){ if (DEBUG) cout << "Connection Failed" << endl; close(sk); sk = -1; return; } if (DEBUG) cout << "Connection OK" << endl; string msg = "GET / HTTP/1.1\r\nHost: " + addr + "\r\nConnection: close\r\n\r\n"; if (send(sk, msg.c_str(), msg.length(), 0) < 0) { if (DEBUG) cout << "Send Failed" << endl; close(sk); sk = -1; return; } ssize_t ret = 0; string html; char read_buf[1024]; while((ret = read(sk, read_buf, sizeof(read_buf))) > 0) { html.append(read_buf, ret); } close(sk); sk = -1; list<string> cont; split(html,cont,'\n'); size_t r = 0; for(auto& line : cont) { if (line.length()>20) { if ((r = line.find("Current IP Address:"))!=string::npos) { string a = line.substr(r+20); a = a.substr(0,a.find("<")); if (DEBUG) cout << a << endl; ip = a; } } } }

六、反思

我在某个项目中为了获取公网ip使用了MyIpAdd::MyIpAdd库。但是它的源码内部有异常退出的bug导致我的程序一直偶发挂掉。所以这给我的启发是:1.尽量用多人用的开源库,小众的开源库没什么人用往往有很多bug;2.一定要有能阅读开源库代码的能力,这样万一开源库出现问题的时候你才能修改这些bug。

相关新闻

  • 终极解密利器AES-Killer:网络安全测试中的AES加密流量实时解密指南
  • 2026年7月最新萧邦大连来福士维修保养服务电话 - 萧邦中国官方服务中心
  • [JCMSuite] JCMSuite应用:等离子波导

最新新闻

  • `githooks` 让 Git 找不到 hook**(你手动 `./githooks/commit-msg` 能跑,但 `git commit` 未必用同一个目录)。
  • Runway绿幕抠像不卡顿、不出错、不重渲:GPU显存分配+缓存预加载+代理序列三重加速方案
  • 2026年深圳PEI板生产厂商选购指南及行业实用参考 - 热点品牌推荐
  • 2026年国产三坐标测量仪企业选型实用参考指南 - 奔跑123
  • 金水区老旧卫生间重做防水服务公司实用选择攻略 - 热点品牌推荐
  • 2026年复合材料类环氧预浸料平价优质厂家汇总推荐 - 奔跑123

日新闻

  • 亨得利盐城维修点在哪里?手表维修保养地址指南**公示(2026年7月最新) - 亨得利官方
  • 提升.NET API安全性:Boxed.AspNetCore.Swagger认证授权最佳实践
  • 帝舵佛山**网点地址更新:2026年7月售后热线电话与服务客户指南 - 帝舵中国官方服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号