本篇内容用于记录我在获取MAC地址时的实现方式以及遇到的多网口时信息读取不全问题,以供后续查阅。
一、获取方式
基于C++获取本机MAC的址的方式有很多,为了代码的简化,采用了CMD命令行运行ipconfig /all的方式。该方式通过Pipe管道捕获命令行输出,再通过CreateProcess创建子进程运行命令行指令,从而获得网络信息的查询结果。再对结果进行检索,得到本机的MAC地址。
创建管道代码
bool bResult = CreatePipe(&hReadHandle, &hWriteHandle, &secutiry_attributes, 0);
创建进程代码
bool bResult = CreateProcess(NULL, L"ipconfig /all", NULL, NULL, TRUE, 0, NULL, NULL, &startup_info, &process_info );
读取返回数据代码
const long MAX_COMMAND_SIZE = 4096;
char szBuffer[MAX_COMMAND_SIZE] = {0};
unsigned long countNum = 0;
WaitForSingleObject (pi.hProcess, 1000/*INFINITE*/);
bool bResult = ReadFile(hReadHandle, szBuffer, MAX_COMMAND_SIZE, &countNum, 0);
至此,就可以读取本地的网口信息了。
二、多网口信息读取不全问题
由于工控机上面存在多个网口,如10个以上。此时,网口信息的数据量会非常大,导致上面的方法无法读取到完整的网口信息。
解决方法通过增加读取容量来获取完整信息,但是增大读取容量后(容量远大于网卡信息数据量),仍然不能获取完整的网卡信息。
解决方案代码
const long MAX_COMMAND_SIZE = 4096*10;
查询微软相关技术文档发现,匿名管道在创建时,使用默认缓存大小,该大小基于系统实际情况分配。因此单次管道传输数据无法保证完整传递网卡信息。而上述代码又只读取了一次。因此出现读取不完整问题。此问题解决方案有两种:多次读取和增大管道缓存。
本次采用第二种
bool bResult = CreatePipe(&hReadHandle, &hWriteHandle, &secutiry_attributes, MAX_COMMAND_SIZE );
至此,读取问题完美解决。