linux系统状态(磁盘大小、内存、进程、cpu使用率、网络连接)
分享一下自己做的一个获取Linux系统状态的类(c++)(代码整理后的,在物理机上测试可以,在vm虚拟机上测试,磁盘计算有问题)
头文件
#ifndef LINUXSERVERSTATE_H
#define LINUXSERVERSTATE_H
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <pthread.h>
#include <map>using std::string;
using std::vector;
using std::map;#pragma pack(push)
#pragma pack(8)
struct SysMemInfo
{unsigned long total;//单位:Munsigned long free;//单位:M
};
struct SysDiskInfo
{string name;//sda1,sad2等等unsigned long total;//单位:M,不包括交换分区、CDROM等unsigned long free;//单位:M
};
struct SysNetInfo
{float send;//kbfloat recv;//kbfloat total;//kb
};
struct SysProcInfo
{string name;//进程名字int pid;//进程idint cpu;//cpu使用率long mem;//内存使用,单位Kb,linux内存指的是vmrss,即程序正在使用的物理内存,-1表示未获取到或获取错误
};
struct SysProcTimeInfo
{unsigned long user;//进程在用户态执行的时间unsigned long kernel;//进程在内核态执行的时间
};
//linux src目录中的include/net/tcp_states.h,source目录一般位于/usr/src/linux*目录中
enum SysNetState{TCP_ESTABLISHED = 1,TCP_SYN_SENT,TCP_SYN_RECV,TCP_FIN_WAIT1,TCP_FIN_WAIT2,TCP_TIME_WAIT,TCP_CLOSE,TCP_CLOSE_WAIT,TCP_LAST_ACK,TCP_LISTEN,TCP_CLOSING, /* Now a valid state */TCP_MAX_STATES /* Leave at the end! */
};
enum SockType{UNKNOWN=0,TCP , UDP, TCP6, UDP6};
struct SysNetConnInfo
{int id;SockType protocol;std::string localAddr;int localPort;std::string remoteAddr;int remotePort;SysNetState state;
};
#pragma pack(pop)void get_netstat(unsigned long& inOctets,unsigned long& outOctets,time_t& sysTime);
void get_cpuusage(unsigned long& cpuTime,unsigned long& idleTime);class LinuxServerState;
void get_procinfo(LinuxServerState* pMain,map<pid_t,SysProcTimeInfo>& procTimeInfo);
void* CPUNetProcessCount(void* arg);class LinuxServerState
{
public:LinuxServerState();virtual ~LinuxServerState();int GetMemInfo(SysMemInfo& memInfo);int GetDiskInfo(vector<SysDiskInfo>& diskInfo,unsigned long &total,unsigned long &available);//返回cpu的利用率,返回-1表示超时或者其他错误int GetCpuUsage();//sys net infoSysNetInfo GetNetInfo();//process infovoid GetProcInfo(vector<SysProcInfo>& procinfo);//net connection infovoid GetNetConnectionInfo(vector<SysNetConnInfo>& netConnInfo);
private:void initialize();friend void* CPUNetProcessCount(void* arg);friend void get_procinfo(LinuxServerState* pMain,map<pid_t,SysProcTimeInfo>& procTimeInfo);int m_cpuUsage; //多个CPU的总的使用率pthread_mutex_t m_mutex;SysNetInfo m_netInfo;pthread_t m_countThread;vector<SysProcInfo> *m_procinfo_cal;vector<SysProcInfo> *m_procinfo;void *m_threadRet;LinuxServerState(const LinuxServerState& other);virtual LinuxServerState& operator=(const LinuxServerState& other);virtual bool operator==(const LinuxServerState& other) const;bool m_running;
};#endif
源文件
#include "sys_stat.h"
#include <sys/sysinfo.h>//getmemInfo
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <climits>
#include <cstring>
#include <time.h>
#include <dirent.h>
#include <errno.h>
#include <iostream>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <algorithm>using namespace std;void get_netstat(unsigned long& inOctets,unsigned long& outOctets,time_t& sysTime)
{unsigned long inNoRoutes = 0, inTruncPkts = 0;unsigned long inMcastPkts = 0, outMcastPkts = 0;unsigned long inBcastPkts = 0, outBcastPkts = 0;unsigned long inMcastOctets = 0, outMcastOctets = 0;unsigned long inBcastOctets = 0, outBcastOctets = 0;fstream fProcNetStat("/proc/net/netstat",ios_base::in);char bufNetStat[2048] = {'\0'}, ipExt[16] = {'\0'};while(!fProcNetStat.eof()){fProcNetStat.getline(bufNetStat,2048);if(strncasecmp(bufNetStat,"tcpext",6) == 0)continue;if(strncasecmp(bufNetStat,"ipext",5) == 0){fProcNetStat.getline(bufNetStat,2048);sscanf(bufNetStat,"%s %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld",ipExt,&inNoRoutes,&inTruncPkts,&inMcastPkts,&outMcastPkts,&inBcastPkts,&outBcastPkts,&inOctets,&outOctets,&inMcastOctets,&outMcastOctets,&inBcastOctets,&outBcastOctets);sysTime = time(NULL);break;}}
}void get_cpuusage(unsigned long& cpuTime,unsigned long& idleTime)
{fstream fProcStat("/proc/stat",ios_base::in);char cpubuf[8] = {'\0'};unsigned long userT = 0, niceT = 0, systemT = 0, idleT = 0;unsigned long ioT = 0, irqT = 0, softirqT = 0;fProcStat>>cpubuf>>userT>>niceT>>systemT>>idleT>>ioT>>irqT>>softirqT;cpuTime = userT + niceT + systemT + idleT + ioT + irqT + softirqT;idleTime = idleT;
}void get_procinfo(LinuxServerState* pMain,map<pid_t,SysProcTimeInfo>& procTimeInfo)
{struct dirent* ent = NULL;char *endptr = NULL;DIR* pDirProc = opendir("/proc");long utime = 0, stime = 0;if(pDirProc == NULL)return ;char dirName[256] = {'\0'};char tmpbuf[2048] = {'\0'};if (pMain->m_procinfo_cal == NULL )return;pMain->m_procinfo_cal->clear();while((ent = readdir(pDirProc))!= NULL){long pidNum = strtol(ent->d_name,&endptr,10);if(pidNum == LONG_MAX || pidNum == LONG_MIN || endptr == ent->d_name)continue;fstream fPidStat,fPidMem;int i = 0;SysProcTimeInfo tmpProcTimeInfo;SysProcInfo tmpProcInfo;snprintf(dirName,256,"%s%d%s","/proc/",pidNum,"/stat");try{fPidStat.open(dirName,ios_base::in);}catch(std::exception& e){continue;}fPidStat>>tmpbuf;//获取pidi++;fPidStat>>tmpbuf;//获取进程名字,名字由"()"包括i++;// process nameif(strlen(tmpbuf) > 2)tmpProcInfo.name = string(tmpbuf).substr(1,strlen(tmpbuf) -2);elsecontinue;for(; i < 14;i++)fPidStat>>tmpbuf;//14项表示utime,15项表示stimefPidStat >> utime;i++;fPidStat >> stime;i++;tmpProcTimeInfo.user = utime;tmpProcTimeInfo.kernel = stime;// process cpu usagemap<pid_t,SysProcTimeInfo>::iterator it = procTimeInfo.find((pid_t)pidNum);if(it == procTimeInfo.end()){procTimeInfo.insert(pair<pid_t,SysProcTimeInfo>(pidNum,tmpProcTimeInfo));tmpProcInfo.cpu = 0;}else{tmpProcInfo.cpu = utime + stime - it->second.kernel - it->second.user;if(tmpProcInfo.cpu > 100)tmpProcInfo.cpu = 100;if(tmpProcInfo.cpu < 0)tmpProcInfo.cpu = 0;it->second.kernel = stime;it->second.user = utime;}utime = 0;stime = 0;tmpProcInfo.pid = pidNum;// process memchar *pstrtolong;memset(dirName,'\0',128);snprintf(dirName,128,"%s%d%s","/proc/",pidNum,"/status");fPidMem.open(dirName,ios_base::in);while(!fPidMem.eof()){fPidMem >> tmpbuf;if(strncasecmp(tmpbuf,"vmrss",5) == 0){fPidMem >> tmpbuf;unsigned long vmrss = strtol(tmpbuf,&pstrtolong,10);if(vmrss == LONG_MAX || vmrss == LONG_MIN || pstrtolong == tmpbuf){tmpProcInfo.mem = -1;}elsetmpProcInfo.mem = vmrss;if(0 == pthread_mutex_trylock(&pMain->m_mutex)){pMain->m_procinfo_cal->push_back(tmpProcInfo);pthread_mutex_unlock(&pMain->m_mutex);}break;}}memset(dirName,'\0',256);memset(tmpbuf,'\0',2048);}closedir(pDirProc);pDirProc = NULL;if(0 == pthread_mutex_trylock(&pMain->m_mutex)){std::swap(pMain->m_procinfo_cal ,pMain->m_procinfo);pthread_mutex_unlock(&pMain->m_mutex);}
}void* CPUNetProcessCount(void* arg)
{LinuxServerState* pMain = (LinuxServerState*)arg;unsigned long inOctets = 0, outOctets = 0;time_t sysTime;unsigned long cpuTime = 0, idleTime = 0;map<pid_t,SysProcTimeInfo> procTimeInfo;while(pMain->m_running){//cpu total usageunsigned long cpuTimeNow = 0, idleTimeNow = 0;int cpu = 0;get_cpuusage(cpuTimeNow,idleTimeNow);cpu = 100 - (idleTimeNow - idleTime)*100/(cpuTimeNow - cpuTime);idleTime = idleTimeNow;cpuTime = cpuTimeNow;if(0 == pthread_mutex_trylock(&pMain->m_mutex)){pMain->m_cpuUsage = cpu;pthread_mutex_unlock(&pMain->m_mutex);}//else暂时不处理//net statunsigned long inOctetsTmp = 0,outOctetsTmp = 0;time_t timeNow = time(NULL);get_netstat(inOctetsTmp,outOctetsTmp,timeNow);SysNetInfo tmpNetInfo;tmpNetInfo.recv = (inOctetsTmp - inOctets)/1024/(timeNow - sysTime);tmpNetInfo.send = (outOctetsTmp - outOctets)/1024/(timeNow - sysTime);tmpNetInfo.total = tmpNetInfo.recv + tmpNetInfo.send;sysTime = timeNow;inOctets = inOctetsTmp;outOctets = outOctetsTmp;if(0 == pthread_mutex_trylock(&pMain->m_mutex)){pMain->m_netInfo = tmpNetInfo;pthread_mutex_unlock(&pMain->m_mutex);}//proc infoget_procinfo(pMain,procTimeInfo);sleep(1);}return NULL;
}LinuxServerState::LinuxServerState()
{m_cpuUsage = 0;m_countThread = 0;m_threadRet = NULL;m_netInfo.total = 0;m_netInfo.recv = 0;m_netInfo.send = 0;m_procinfo_cal = new vector<SysProcInfo>();m_procinfo = new vector<SysProcInfo>();m_running = true;initialize();
}LinuxServerState::LinuxServerState(const LinuxServerState& other)
{
}LinuxServerState::~LinuxServerState()
{m_running = false;if(m_countThread != 0)pthread_join(m_countThread,NULL);pthread_mutex_destroy(&m_mutex);if ( m_procinfo != NULL )delete m_procinfo;if ( m_procinfo_cal != NULL )delete m_procinfo_cal;
}LinuxServerState& LinuxServerState::operator=(const LinuxServerState& other)
{return *this;
}bool LinuxServerState::operator==(const LinuxServerState& other) const
{///TODO: return ...;
}void LinuxServerState::initialize()
{pthread_mutex_init(&m_mutex,NULL);pthread_create(&m_countThread,NULL,&CPUNetProcessCount,this);
}int LinuxServerState::GetCpuUsage()
{timespec tmp;tmp.tv_nsec = 0;tmp.tv_sec = 1;int cpu = 0;if(0 == pthread_mutex_timedlock(&m_mutex,&tmp)){cpu = m_cpuUsage;pthread_mutex_unlock(&m_mutex);}if(cpu > 100)return 100;if(cpu < 0)return 0;return cpu;
}int LinuxServerState::GetMemInfo(SysMemInfo& memInfo)
{struct sysinfo tmp;int ret = sysinfo(&tmp);if(ret == 0){memInfo.free = (unsigned long)tmp.freeram/(1024*1024);memInfo.total = (unsigned long)tmp.totalram/(1024*1024);}return ret;
}int LinuxServerState::GetDiskInfo(std::vector<SysDiskInfo>& diskInfo,unsigned long &total,unsigned long &available)
{total = 0;available = 0;char buf[128] = {'\0'};string fileName;char *p;fstream fProc("/proc/partitions",ios_base::in);unsigned long total2 = 0, free2 = 0, sumTotal = 0, sumFree = 0;int major = 0, minor = 0;//首先计算总大小及各个分区的大小,包括交换分区,然后用df命令获取可用空间while(!fProc.eof()){fProc>>fileName;total2 = strtol(fileName.c_str(),&p,10);if(total2 == 0)continue;else if(total2 == LONG_MAX || total2 == LONG_MIN || p == fileName.c_str())return total2;else{major = total2;fProc>>minor;fProc>>total2;fProc>>fileName;SysDiskInfo tmp;tmp.total = (unsigned long)(total2/1024);tmp.free = 0;tmp.name = fileName;diskInfo.push_back(tmp);if((fileName.find("sd")!= string::npos || fileName.find("hd") != string::npos) &&!(fileName[fileName.size()-1] >='0' && fileName[fileName.size()-1] <='9'))sumTotal += tmp.total;fileName.clear();}}//获取可用空间const char *command = "df";const char *type = "r";FILE *pFile = popen(command,type);char buf2[1024] = {'\0'};char filesys[64] = {'\0'}, usage[8] = {'\0'}, mountedon[64] = {'\0'};unsigned long kblocks = 0, used = 0, available2 = 0;if(pFile == NULL)return -1;vector<SysDiskInfo>::iterator it;while (!feof (pFile) ){if (fgets (buf2 , 1024 , pFile) == NULL )break;sscanf(buf2,"%s %ld %ld %ld %s %s",filesys,&kblocks,&used,&available2,usage,mountedon);string ff(filesys);if(ff.rfind("/") == string::npos)continue;for(it = diskInfo.begin(); it != diskInfo.end();it++){if(it->name == ff.substr(ff.rfind("/")+1)){it->free = (unsigned long)(available2/1024);sumFree += it->free;}}memset(buf2,'\0',1024);memset(filesys,'\0',64);memset(mountedon,'\0',64);memset(usage,'\0',8);kblocks = 0;used = 0;available2 = 0;}pclose(pFile);total = sumTotal;available = sumFree;return 0;
}SysNetInfo LinuxServerState::GetNetInfo()
{SysNetInfo tmpNetInfo;tmpNetInfo.recv = 0;tmpNetInfo.send = 0;tmpNetInfo.total = 0;timespec tmp;tmp.tv_nsec = 0;tmp.tv_sec = 1;if(0 == pthread_mutex_timedlock(&m_mutex,&tmp)){tmpNetInfo = m_netInfo;pthread_mutex_unlock(&m_mutex);}return tmpNetInfo;
}void LinuxServerState::GetProcInfo(std::vector<SysProcInfo>& procinfo)
{timespec tmp;tmp.tv_nsec = 0;tmp.tv_sec = 1;if(0 == pthread_mutex_timedlock(&m_mutex,&tmp)){if ( m_procinfo == NULL )return;procinfo = *m_procinfo;pthread_mutex_unlock(&m_mutex);}
}void LinuxServerState::GetNetConnectionInfo(std::vector<SysNetConnInfo>& netConnInfo)
{int i = 0,id = 0;char buf[1024] = {'\0'};while(i++ < 4){fstream fInfo;SockType stateType = UNKNOWN;if(i == 1){fInfo.open("/proc/net/tcp",ios_base::in);stateType = TCP;}else if(i == 2){fInfo.open("/proc/net/udp",ios_base::in);stateType = UDP;}else if(i == 3){fInfo.open("/proc/net/tcp6",ios_base::in);stateType = TCP6;}else if(i == 4){fInfo.open("/proc/net/udp6",ios_base::in);stateType = UDP6;}if(stateType == UNKNOWN)continue;while(!fInfo.eof()){SysNetConnInfo tmpConnInfo;char sl[6] = {'\0'},localaddr[32] = {'\0'},remoteaddr[32] = {'\0'};fInfo.getline(buf,1024);unsigned long llocal = 0, lremote = 0;int localPort = 0, remotePort = 0, st = 0;int ret;if(i == 1 || i == 2){ret = sscanf(buf,"%s%x:%x%x:%x%x",sl,&llocal,&localPort,&lremote,&remotePort,&st);if(ret != 6)continue;in_addr tmpAddr;tmpAddr.s_addr = llocal;tmpConnInfo.localAddr = inet_ntoa(tmpAddr);tmpAddr.s_addr = lremote;tmpConnInfo.remoteAddr = inet_ntoa(tmpAddr);}else if(i == 3 || i == 4 ){ret = sscanf(buf,"%s%32s:%x%32s:%x%x",sl,&localaddr,&localPort,&remoteaddr,&remotePort,&st);if(ret != 6)continue;char tmp[64] = {'\0'};int pos = 0;for(int j = 0;j < 32; j++){tmp[pos++] = localaddr[j];if((j % 4) == 3 && j != 31)tmp[pos++] = ':';}tmpConnInfo.localAddr = string(tmp);memset(tmp,'\0',64);pos = 0;for(int j = 0;j < 32; j++){tmp[pos++] = remoteaddr[j];if((j % 4) == 3 && j != 31)tmp[pos++] = ':';}tmpConnInfo.remoteAddr = string(tmp);}tmpConnInfo.localPort = localPort;tmpConnInfo.remotePort = remotePort;tmpConnInfo.id = id++;tmpConnInfo.protocol = stateType;tmpConnInfo.state = (SysNetState)st;netConnInfo.push_back(tmpConnInfo);}fInfo.close();}
}
测试文件
#include <iostream>
#include "sys_stat.h"using namespace std;int main(int argc, char *argv[])
{if (argc < 2){cout<<"usage:"<<endl;cout<<"\t./test mem/disk/cpu/proc/net/conn"<<endl;return 0;}string opt(argv[1]);int i = 0;LinuxServerState stat;while ( i++ < 10 ){if (opt == "cpu"){cout << "cpu_use:"<<stat.GetCpuUsage()<<endl;}else if (opt == "mem"){SysMemInfo meminfo;stat.GetMemInfo(meminfo);cout<<"meminfo:"<<endl;cout<<"\ttotal:"<<meminfo.total<<"M"<<endl;cout<<"\tfree:"<<meminfo.free<<"M"<<endl;cout<<"\t"<<((double)(meminfo.total - meminfo.free))*100/meminfo.total<<endl;}else if (opt == "disk"){vector<SysDiskInfo> vdiskinfo;unsigned long disktotal,diskavail;stat.GetDiskInfo(vdiskinfo,disktotal,diskavail);cout<<"diskinfo:"<<endl;cout<<"\ttotal:"<<disktotal<<"M"<<endl;cout<<"\tfree:"<<diskavail<<"M"<<endl;cout<<"\t"<<((double)(disktotal - diskavail))*100/disktotal<<endl;vector<SysDiskInfo>::iterator itdisk = vdiskinfo.begin();cout<<endl;for(; itdisk != vdiskinfo.end(); ++itdisk){cout<<"\tname:"<<itdisk->name<<endl;cout<<"\ttotal:"<<itdisk->total<<"M"<<endl;cout<<"\tfree:"<<itdisk->free<<"M"<<endl;cout<<endl;}}else if (opt == "net"){SysNetInfo netinfo = stat.GetNetInfo();cout<<"netinfo:"<<endl;cout<<"\trecv:"<<netinfo.recv<<"kb"<<endl;cout<<"\tsend:"<<netinfo.send<<"kb"<<endl;cout<<"\ttotal:"<<netinfo.total<<"kb"<<endl;}else if (opt == "proc"){vector<SysProcInfo> procinfo;stat.GetProcInfo(procinfo);cout<<"procinfo:"<<endl;vector<SysProcInfo>::iterator itproc = procinfo.begin();for(; itproc != procinfo.end(); ++itproc){cout<<"\tname:"<<itproc->name<<endl;cout<<"\tpid:"<<itproc->pid<<endl;cout<<"\tmem:"<<itproc->mem<<"Kb"<<endl;cout<<"\tcpu:"<<itproc->cpu<<endl;cout<<endl;}}else if (opt == "conn"){vector<SysNetConnInfo> netConnInfo;stat.GetNetConnectionInfo(netConnInfo);vector<SysNetConnInfo>::iterator itconn = netConnInfo.begin();for(; itconn!= netConnInfo.end(); ++itconn){cout<<"\tid:"<<itconn->id<<endl;cout<<"\tprotocol:"<<itconn->protocol<<endl;cout<<"\tlocalAddr:"<<itconn->localAddr<<":"<<itconn->localPort<<endl;cout<<"\tremoteAddr:"<<itconn->remoteAddr<<":"<<itconn->remotePort<<endl;cout<<"\tstate:"<<itconn->state<<endl;cout<<endl;}}sleep(1);}sleep(1);return 0;
}
makefile
target=testsrc=$(wildcard ./*.cpp)
objs=$(patsubst %.cpp,%.o,$(src))%.o:%.cppg++ -g -c $<${target}:${objs}g++ -o $@ ${objs} -lpthreadclean:rm ./*.orm ./test
转载于:https://blog.51cto.com/hakuyo/1218145
linux系统状态(磁盘大小、内存、进程、cpu使用率、网络连接)相关推荐
- Linux top指令 能够根据内存,cpu使用率来进行排序
Linux top指令 能够根据内存,cpu使用率来进行排序 根据内存排序 top后 输入M 由于公司要求,不能暴露太多信息,因此不上图了,自己尝试下就知道了 根据cpu排序 top后 输入P 还能 ...
- linux查看docker使用率,Linux系统非Docker环境如何限制CPU使用率
微服务时代,有时候为了方便,经常在一台高配置服务器运行很多服务,这个时候CPU资源抢占就成了一个非常头痛的问题.闲时不会出现什么问题,比如一台16核服务器,当某一个时刻某个微服出现高并发访问时,此服务 ...
- 如何查看linux系统服务器磁盘大小和文件占用情况
最近维护一个系统,每天动不动就挂掉,以为是程序的问题,但是看日志程序也没有报错 那是不是系统那个地方的问题 于是就这样想了 是不是磁盘空间满了,作为一个开发,我还不知道如何去看磁盘的空间大小,于是请了 ...
- 监控Linux系统状态的命令
监控Linux系统状态的命令1 :w uptime命令查看系统负载 : w/uptime 最后面三个数字表示1分钟 ,5分钟 ,15分钟 平均有多少进程占用CPU 某一时刻1颗CPU只能有一个进程在使 ...
- linux ps内存占用率,linux ps命令,查看某进程cpu和内存占用率情况, linux ps命令,查看进程cpu和内存占用率排序。 不指定...
背景:有时需要单看某个进程的CPU及占用情况,有时需要看整体进程的一个占用情况. 一. linux ps命令,查看某进程cpu和内存占用率情况 [root@test vhost]# ps aux US ...
- Linux系统状态检测及进程控制--2
Linux系统状态检测及进程控制--1(http://crushlinux.blog.51cto.com/2663646/836481) 4.僵死(进程已终止,但进程描述符存在,直到父进程调用wait ...
- linux查看usr利用率,在Linux中通过Top运行进程查找最高内存和CPU使用率
我记得一次阅读,高效的系统管理员是懒惰的人.原因不是他们不在做他们的工作或浪费他们的时间 - 这主要是因为他们已经自动化了大量的日常任务.因此,他们不必保管他们的服务器,可以利用他们的时间学习新技术, ...
- Linux系统查询磁盘空间大小(df、du)
df命令是linux系统以磁盘分区为单位查看文件系统,可以加上参数查看磁盘剩余空间信息, 命令格式:df -hl 显示格式为: 文件系统 容量 已用 可用 ...
- 监控linux系统状态
监控linux系统状态 监控介绍 安装zabbix4.0 监控客户机 解决中文名称不能写数据库的问题 解决图形中乱码 zabbix邮件告警 zabbix监控Nginx zabbix监控Tomcat z ...
最新文章
- U3D的Collider
- .NET 4.0有一个新的GAC,为什么?
- 单片机 多机通讯c语言,单片机多机串口通信.doc
- m3u8文件在手机上用什么软件看_新技能Get!教你制作m3u8文件 创建属于自己的直播视频列表...
- boost::graph模块实现包含平均测地线示例
- 权限操作-springSecurity概述及快速入门步骤分析
- HDOJ1860 ( 统计字符 ) 【水题】
- C# RichTextBox 做简单的HTML代码编辑器 ---------利用WinApi修正左侧显示行号 误差
- 大一上期c语言实验报告2,大一上期C语言实验报告1熟悉实验环境
- 判断两个ListInteger是否包含同样的值,不考虑位置关系
- SQL之总结(四)---null问题的处理
- 张量Tensor@最强分析
- cad插入块_CAD软件中图块无法分解怎么办?
- 一个留美女博士的七年----分享给所有还相信梦想的朋友(zz 喜欢~~)
- 通信原理包络是什么意思_为什么齿轮不能少于17个齿,少于17个齿,齿轮传动会如何?...
- 你是否错过了母校的AI本科专业?盘点2020国内本科开设人工智能专业高校
- 抑郁症治疗过程中有哪些变化?
- birthday中文是什么_ffappybirthday翻译
- 非监督分类ecognition_资管新规学习03资管产品的范围和分类
- 网站搬家,服务器迁移注意事项有哪些?