Linux 下通过ping判断机器有没有外网。(不用root)
背景:
想实现一个判断当前系统有没有外网的方法,想到了两种思路:
1)实现一个ICMP协议。但是这个需要root权限才能运行。可以参考:https://www.cnblogs.com/xcywt/p/16070814.html
2)通过ping指令,解析ping的结果来判断有没有网。
代码:
0)命令:system("ping 192.168.1.21 -c 2 > PingTempTest.txt"); // -c 2 表示ping两次。
1)再去解析PingTempTest.txt中的内容。
3)实际使用时由于ping是耗时操作,为了不阻塞主线程,开了一个子线程去调用ping。
4)注意:如果系统是中文版本,可能ping运行的结果格式不一致。将无法使用下面的解析方法。
5)编译时需要指定C++14,和链接线程库。
头文件:
/*
* @author:xcywt
* @date:2022-03-30
* @contact me: https://www.cnblogs.com/xcywt/
*/ #ifndef __DDR_CHECKFOREXTRANET_H__
#define __DDR_CHECKFOREXTRANET_H__ #include <string> namespace DDRSys
{
/*
检测有没有外网的。原理就是:尝试ping某个ip,然后解析ping的结果。
每次创建一个对象会开辟一个线程。在线程中循环ping。
可以通过 GetNetState 取得结果。 测试系统:ubuntu16.04
用法:
void test_20220330()
{
DDRSys::CheckForExtranet check;
check.SetPingIntervals(10);
//check.SetPingIp("114.114.114.114");
//check.SetPingIp("114.114.114.11");
//check.SetPingIp("8.8.8.8");
//check.SetPingIp("8.8.8.7");
check.SetPingIp("192.168.1.21");
int nnn = 0;
while (1)
{
nnn++;
//printf("test_20220330() nnn:%d State:%d\n", nnn, check.GetNetState());
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
if (nnn > 100)
break;
}
} 编译时需要指定C++14,和链接线程库。
g++ main.cpp CheckForExtranet.cpp -std=c++14 -lpthread
*/ class CheckForExtranet
{
public:
CheckForExtranet(); ~CheckForExtranet(); // 设置需要ping的ip,一般指定 8.8.8.8 或者 114.114.114.114
void SetPingIp(std::string ip); // 设置间隔时间。单位为秒。设置为10,表示每隔10秒尝试ping一次
void SetPingIntervals(int sec); // -1:表示无效值 0:没网 1:有网
int GetNetState(); private:
class IMPL;
IMPL *m_pImp = nullptr;
};
} #endif // __DDR_CHECKFOREXTRANET_H__
源文件:
#include "CheckForExtranet.h"
#include <thread>
#include <mutex>
#include <fstream>
#include <vector> namespace DDRSys
{
std::vector<std::string> split(const std::string &text, char sep)
{
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
if (end != start) {
tokens.emplace_back(text.substr(start, end - start));
}
start = end + 1;
}
if (end != start) {
tokens.emplace_back(text.substr(start));
}
return tokens;
} class CheckForExtranet::IMPL
{
public:
IMPL()
{
m_subThread = std::thread(subThread, (void*)this);
} ~IMPL()
{
printf("[%s] CheckForExtranet::IMPL::~IMPL() +++ \n", GetLogPrev().c_str()); if (1)
{
std::lock_guard<std::mutex> lll(m_mutex);
m_bQuit = true;
}
if (m_subThread.joinable())
{
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
m_subThread.join();
} printf("[%s] CheckForExtranet::IMPL::~IMPL() --- \n", GetLogPrev().c_str());
} std::string GetLogPrev()
{
return "ExtranetLog";
//return DDRSys::GetCurTimeStamp_MilSec(); // 这个函数返回当时时间戳的
} void SetPingIp(std::string ip)
{
std::lock_guard<std::mutex> lll(m_mutex);
m_strPingIp = ip;
} void SetPingIntervals(int sec)
{
std::lock_guard<std::mutex> lll(m_mutex);
m_Intervals = sec;
} int GetNetState()
{
std::lock_guard<std::mutex> lll(m_mutex);
auto curr = m_nState;
return curr;
} void _myLoop()
{
printf("[%s] CheckForExtranet::IMPL::_myLoop() +++ \n", GetLogPrev().c_str()); const int waitTime = 500;
int waitCount = -1;
while (1)
{
int Intervals = 0;
bool bQuit = false;
if (1)
{
std::lock_guard<std::mutex> lll(m_mutex);
bQuit = m_bQuit;
Intervals = m_Intervals;
} if (bQuit)
{
break;
} std::this_thread::sleep_for(std::chrono::milliseconds(waitTime));
if ((waitCount > (m_Intervals * 1000) / waitTime) || (waitCount < 0))
{
waitCount = 0;
Ping();
}
waitCount++;
}
printf("[%s] CheckForExtranet::IMPL::_myLoop() --- \n", GetLogPrev().c_str());
} static void subThread(void *param)
{
if (param)
{
auto *pThis = (CheckForExtranet::IMPL*)param;
pThis->_myLoop();
}
} void Ping()
{
std::string strip = "";
if (1)
{
std::lock_guard<std::mutex> lll(m_mutex);
strip = m_strPingIp;
} std::string fileNameTemp("PingTempTest");
fileNameTemp += ".txt"; std::string cmd("ping ");
cmd += strip;
cmd += " -c 2 > ";
cmd += fileNameTemp;
printf("[%s] Start ping:%s cmd:[%s] ++++ \n", GetLogPrev().c_str(),strip.c_str(), cmd.c_str());
system(cmd.c_str()); // cmd eg:ping 192.168.1.21 -c 2 > PingTempTest.txt
// 这里是解析上面的结果。如果系统是中文版本,可能ping运行的结果格式不一致。将无法使用下面的解析方法。
int state = -1;
std::vector<std::string> vecTTT;
std::ifstream in(fileNameTemp.c_str());
if (in.is_open())
{
std::string s;
while (getline(in, s))
{
vecTTT.push_back(s);
}
in.close();
} for (auto item : vecTTT)
{
if ((int)item.find("packet loss") > 0)
{
// 2 packets transmitted, 0 received, 100% packet loss, time 1001ms
auto vec = split(item, ','); // 这个函数是分隔用的。根据逗号分隔,结果放在vec中。
for (auto ii : vec)
{
if ((int)ii.find("packet loss") > 0)
{
int index = ii.find("%");
std::string str;
str.assign(ii.begin(), ii.begin() + index);
int packetLoss = std::atoi(str.c_str());
if (packetLoss >= 80)
state = 0; // 丢失率大于80%就认为是没网了
else
state = 1;
printf("[%s] ReadInfo:%s packetLoss:%d state:%d\n", GetLogPrev().c_str(), ii.c_str(), packetLoss, state);
break;
}
}
break;
}
} /*
dadao@dadao:~$ ping 8.8.8.8 -c 2
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=48.8 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=50.3 ms --- 8.8.8.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 48.893/49.609/50.326/0.750 ms
dadao@dadao:~$ ping 8.8.8.82 -c 2
PING 8.8.8.82 (8.8.8.82) 56(84) bytes of data. --- 8.8.8.82 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1001ms dadao@dadao:~$
*/ if (1)
{
std::lock_guard<std::mutex> lll(m_mutex);
m_nState = state;
}
std::this_thread::sleep_for(std::chrono::milliseconds(10));
printf("[%s] End ping:%s state:%d ---- \n", GetLogPrev().c_str(), strip.c_str(), state);
} private:
std::thread m_subThread;
std::mutex m_mutex;
bool m_bQuit = false; int m_nState = -1; // // -1表示结果无意义 0表示没网 1表示有网
std::string m_strPingIp = "8.8.8.8";
int m_Intervals = 10;
}; CheckForExtranet::CheckForExtranet()
{
m_pImp = new CheckForExtranet::IMPL();
} CheckForExtranet::~CheckForExtranet()
{
if (m_pImp)
{
m_pImp->~IMPL();
m_pImp = nullptr;
}
} void CheckForExtranet::SetPingIp(std::string ip)
{
if (m_pImp)
{
m_pImp->SetPingIp(ip);
}
} void CheckForExtranet::SetPingIntervals(int sec)
{
if (m_pImp)
{
m_pImp->SetPingIntervals(sec);
}
} int CheckForExtranet::GetNetState()
{
if (m_pImp)
{
return m_pImp->GetNetState();
}
return -1;
} }
实际效果:
dadao@dadao:~/workspace/test/PIng$ ./a.out
[ExtranetLog] CheckForExtranet::IMPL::_myLoop() +++
[ExtranetLog] Start ping:192.168.1.21 cmd:[ping 192.168.1.21 -c 2 > PingTempTest.txt] ++++
[ExtranetLog] ReadInfo: 0% packet loss packetLoss:0 state:1
[ExtranetLog] End ping:192.168.1.21 state:1 ----
[ExtranetLog] Start ping:192.168.1.21 cmd:[ping 192.168.1.21 -c 2 > PingTempTest.txt] ++++
[ExtranetLog] ReadInfo: 0% packet loss packetLoss:0 state:1
[ExtranetLog] End ping:192.168.1.21 state:1 ----
Linux 下通过ping判断机器有没有外网。(不用root)的更多相关文章
- Windows 和 Linux 下 禁止ping的方法
Windows 和Linux 下 禁止ping的方法 目的: 禁止网络上的其他主机或服务器ping自己的服务器 运行环境: Windows 03.08 linux 方法: Windows 03下: ...
- Linux 下 CPU 使用率与机器负载的关系与区别
原文链接: http://blog.chinaunix.net/uid-28541347-id-4926054.html 当我们使用top命令查看系统的资源使用情况时会看到load average, ...
- Linux下实现ping功能
实现ping功能,就肯定要用到ping命令,那么在Linux下ping命令为: ping [-dfnqrRv][-c<完成次数>][-i<间隔秒数>][-I<网络界面&g ...
- 虚拟机Linux下解决ping时出现 unknown host问题
在虚拟机中使用CentOS6.5时,ping www.baidu.com出现报错信息:“ping: unknown hostwww.baidu.com”,虚拟机和物理机网络连接是NAT方式,物理机访问 ...
- 扔掉360:Linux下无线网卡作WiFi路由器(转薄荷开源网)
这个话题很多人感兴趣,毕竟现在是无线互联时代.手机一族到外面去,首先关心的就是有没有 WiFi.Windows 7 用户可以安装 360 的软件,把笔记本电脑配置成路由器,供手机或其他电脑上网. 在 ...
- 判断内网机器的真实外网IP或域名的方法总结
在内渗透中有时需要在某台WEB服务器中留下后门,可以通过内网IP建立IPC连接,但还需要获知外网IP才能访问Wbshell,在无网关权限的情况下,我总结了有如下方法: nslookup myip.op ...
- centOS7 可以ping通主机不能访问外网
前言: 突然打开自己前不久在虚拟机安装的centOS7系统,发现以前可以来联网突然不能访问外网,在网上看了很多方法,终于解决 问题描述: 连上网,但是ping 不同外网,如ping www.baodu ...
- VM中Linux网络设置(固定ip、连接外网开发环境)
在开发过程中,我们经常需要在linux中进行操作.毕竟服务器的系统大多数都是Linux,所以在dev环境需要配置好一台Linux系统配合开发. 在VMWare Workstation Pro中 ...
- linux下的ping工具--fping
前言: 如果想ping 大量的不连续的地址,有想知道放回结果,在linux系统下有一个非常合适的工具--fping. Fping 官网:http://www.fping.org/ Fpin ...
随机推荐
- Asp.net core IdentityServer4与传统基于角色的权限系统的集成
写在前面 因为最近在忙别的,好久没水文了 今天来水一篇: 在学习或者做权限系统技术选型的过程中,经常有朋友有这样的疑问 : "IdentityServer4的能不能做到与传统基于角色的权限系 ...
- Python 中 selenium 库
目录 selenium 基础语法 一. 环境配置 1. 安装环境 2. 配置参数 3. 常用参数搭配 4. 分浏览器启动 二. 基本语法 1. 元素定位 2. 控制浏览器操作 3. 操作元素的方法 3 ...
- 2021年都要过去啦,你还在用Excel做数据可视化效果吗?
2021年都要过去啦,你还在用Excel做数据可视化效果吗?古语有云,"工欲善其事,必先利其器",没有专业的工具,前期准备的再好也是白搭.现在运用数据可视化工具于经营活动中的企业是 ...
- 赶紧收藏!最好用的BI工具都在这了!
1.bi厂商--思迈特软件Smartbi 广州思迈特软件有限公司成立于2011 年,以提升和挖掘企业客户的数据价值为使命,专注于商业智能与大数据分析软件产品与服务.思迈特软件是国家认定的"高 ...
- 大数据Hadoop-Spark集群部署知识总结(一)
大数据Hadoop-Spark集群部署知识总结 一.启动/关闭 hadoop myhadoop.sh start/stop 分步启动: 第一步:在hadoop102主机上 sbin/start-dfs ...
- 【windows 操作系统】【CPU】用户模式和内核模式(用户层和内核层)
所有的现代操作系统中,CPU是在两种不同的模式下运行的: 注意以下内容来自微软: windows用户模式和内核模式 运行 Windows 的计算机中的处理器有两个不同模式:用户模式 和内核模式 . 用 ...
- 【C# 程序集】把自己的程序集添加|卸载 到GAC 全局程序集缓存中
添加全局程序集缓存 Global Assembly Cache Tool (Gacutil.exe) 操作环境windows10+vs2019 cmd.exe位置在 C:\Windows\System ...
- 多态在C#中的应用
C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容.这具有多方面的意义.例如,这意味着在基类中引入与派生类中的某个成员具有相同名称的新成员在 C# 中是 ...
- 通过xmanager连接linux远程主机桌面
转至:https://blog.csdn.net/kadwf123/article/details/79564293 1.效果图: 远程linux桌面版主机,此处是虚拟机: 使用xmanager xb ...
- Symfony Bundle开发视频教程分享
之前分享了自己录制的<Symfony 5全面开发>视频教程,收到的反馈不错,说学到了东西,讲的很深入等等. 上一次分享的链接:自己录制的Symfony5视频教程,免费分享给大家学习. 小晒 ...