文章目录
三种数据通信传输模式一、单工通信
数据传输只支持数据在一个方向上传输;在同一时间只有一方能接受或发送数据信息,不能实现双向通信。比较安全,例如:广播、电视。
二、半双工通信
传输允许数据在两个方向上传输;在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;在同一时间只可以有一方接受或发送消息,可以实现双向通信。例如:对讲机。
三、全双工通信
数据通信允许数据同时在两个方向上传输,全双I通信是两个单工通信方式的组合。它要求发送设备和接收设备都有独立的接收和发送能力;在同一时间可以同时接受和发送消息。例如:电话通信。
相关基础知识1、__stdcall
2、GetIfTable()函数
函数
DWORD GetIfTable(
PMIB_IFTABLE pIfTable,
PULONG pdwSize,
BOOL bOrder
);
功能
获取MIB-II接口列表
参数
PMIB_IFTABLE pIfTable:接收缓冲区,接收GetIfTable返回的MIB-II接口表
PULONG pdwSize:pIfTable缓冲区字节数,若缓冲区过小则返回所需大小
BOOL bOrder:指定pIfTable中返回的接口列表条目是否根据接口索引排序
3、MIB_IFTABLE结构体
MIB_IFTABLE结构体
typedef struct _MIB_IFTABLE {
DWORD dwNumEntries;
MIB_IFROW table[ANY_SIZE];
} MIB_IFTABLE, *PMIB_IFTABLE;
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
DWORD dwIndex;
DWORD dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
BYTE bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
DWORD dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
BYTE bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;
返回值
成功返回NO_ERROR,否则返回值即错误码
头文件和引用库
#include <IPHlpApi.h>
#pragma comment(lib, "IPHlpApi.lib")
细说MIB_IFROW结构体成员
dwType:接口类型,例如IF_TYPE_ETHERNET_CSMACD=6, Ethernet网络接口;
IF_TYPE_SOFTWARE_LOOPBACK=24,软件回环测试网络接口。23号之前的网络接口可用来统计系统流量。
dwSpeed:接口速度,单位bps,可用来计算网络带宽
bPhysAddr:接口网卡的MAC地址
dwInOctets:接收的字节数,自系统启动,可用来统计系统网络流量。
dwOutOctets:发送的字节数,自系统启动,可用来统计系统网络流量。
4、获取网络带宽
bool GetNetworkBandwithByMidTable(int &iMbsBandwidth)
{
/*获取MIB-II接口表大小*/
DWORD dwBufferLen = 0;
GetIfTable(NULL, &dwBufferLen, 0);
/*创建MIB-II接口表*/
PMIB_IFTABLE pMibIfTable = (MIB_IFTABLE*)malloc(dwBufferLen);
/*获取MIB-II接口表*/
DWORD dwRet = GetIfTable(pMibIfTable, &dwBufferLen, 0);
if(NO_ERROR != dwRet)
{
std::cout<<"GetIfTable != NO_ERROR, ErrorCode="<<dwRet<<std::endl;
free(pMibIfTable);
return false;
}
iMbsBandwidth = INT_MAX;
/*多网卡*/
for(int i = 0; i != pMibIfTable->dwNumEntries; ++i)
{
if (pMibIfTable->table[i].dwType <= 23)
{
int iTmp = static_cast<int>(pMibIfTable->table[i].dwSpeed/1000/1000);
if(iTmp != 0 && iTmp < iMbsBandwidth)
iMbsBandwidth = iTmp;
}
}
free(pMibIfTable);
if(iMbsBandwidth == INT_MAX)
return false;
return true;
}
网卡的传输速度有10Mbps、100Mbps、1000Mbps,查看网卡速度的方法:设备管理器—网络适配器—选择网卡—属性—高级—连接速度和双工模式—值—下拉菜单中的最大值。
网络带宽由多种因素决定,例如为连接在只具备100M传输速度的双绞线上的计算机配置1000M的网卡就是一种浪费,因为其至多也只能实现100M的传输速率。
故网络带宽为各种物理介质中的最小值,可认为是所有网卡传输速度的最小值(且不为0)。
5、获取发送比特数和接收比特数,自系统启动
bool GetStatisticOfSysNetworkFlow(DWORD &dwbitTotalRecv, DWORD &dwbitTotalSend)
{
/*获取MIB-II接口表大小*/
DWORD dwBufferLen = 0;
GetIfTable(NULL, &dwBufferLen, 0);
/*创建MIB-II接口表*/
PMIB_IFTABLE pMibIfTable = (MIB_IFTABLE*)malloc(dwBufferLen);
/*获取MIB-II接口表*/
DWORD dwRet = GetIfTable(pMibIfTable, &dwBufferLen, 0);
if(NO_ERROR != dwRet)
{
std::cout<<"GetIfTable != NO_ERROR, ErrorCode="<<dwRet<<std::endl;
free(pMibIfTable);
return false;
}
dwbitTotalRecv = dwbitTotalSend = 0;
/*多网卡*/
for(int i = 0; i != pMibIfTable->dwNumEntries; ++i)
{
if (pMibIfTable->table[i].dwType <= 23)
{
dwbitTotalRecv += pMibIfTable->table[i].dwInOctets;
dwbitTotalSend += pMibIfTable->table[i].dwOutOctets;
}
}
/*Byte转bit*/
dwbitTotalRecv *= 8;
dwbitTotalSend *= 8;
free(pMibIfTable);
return true;
}
6、计算每秒发送比特数和每秒接收比特数
bool GetSysNetworkFlowByMidTable(DWORD &dwbpsRecv, DWORD &dwbpsSend)
{
/*首次获取*/
DWORD dwTotalRecv1 = 0, dwTotalSend1 = 0;
if(!GetStatisticOfSysNetworkFlow(dwTotalRecv1, dwTotalSend1))
{
printf("GetStatisticOfSysNetworkFlow == false\n");
return false;
}
Sleep(1000);
/*再取*/
DWORD dwTotalRecv2 = 0, dwTotalSend2 = 0;
if(!GetStatisticOfSysNetworkFlow(dwTotalRecv2, dwTotalSend2))
{
printf("GetStatisticOfSysNetworkFlow == false\n");
return false;
}
/*计算*/
dwbpsRecv = dwTotalRecv2 - dwTotalRecv1;
dwbpsSend = dwTotalSend2 - dwTotalSend1;
return true;
}
7、SetupDiGetClassDevs()函数
SetupDiGetClassDevs用来查询与指定参数匹配的所有已安装设备。
函数定义
HDEVINFO
SetupDiGetClassDevs(
const GUID* ClassGuid,
PCTSTR Enumerator,
HWND hwndParent,
DWORD Flags
);
参数说明
PGUIDClassGuid
在创建设备列表的时候提供一个指向GUID的指针。如果设定了标志(参数Flags的值)为DIGCF_ALLCLASSES,则这个参数可以忽略,且列表结果中包括所有已经安装的设备类别。
PCTSTREnumerator
提供包含设备实例的枚举注册表分支下的键名,可以通过它获取设备信息。如果这个参数没有指定,则要从整个枚举树中获取所有设备实例的设备信息。
HWNDhwndParent
提供*窗口的句柄,所有用户接口可以使用它来与成员联系。
DWORDFlags
提供在设备信息结构中使用的控制选项。可以是以下数值:
DIGCF_PRESENT - 只返回当前存在的设备。
DIGCF_ALLCLASSES - 返回所有已安装的设备。如果这个标志设置了,ClassGuid参数将被忽略。
DIGCF_PROFILE - 只返回当前硬件配置文件中的设备。
DIGCF_INTERFACEDEVICE - 返回所有支持的设备。
DIGCF_DEFAULT - 只返回与系统默认设备相关的设备。
返回值
HDEVINFO
如果函数运行成功,返回设备信息结构的句柄,该结构包含与指定参数匹配的所有已安装设备。如果失败,则返回INVALID_HANDLE_VALUE。调用GetLastError可以获得更多错误信息。
说明
使用此函数,需要包含头文件setupapi.h。
此外,在project setting中的link页面需要添加setupapi.lib。
在setupapi.h中有如下定义:
typedef PVOID HDEVINFO;
即HDEVINFO是个无类型指针
举例
//得到所有设备
HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, 0, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES );