三菱PLC slmp(mc)协议
//对于三菱PLC,可参考mx component5.0(详见以前的文章)通讯
//本文自写解析协议。
//本文在 c++ builder平台和FX5U调试成功
#ifndef _SlmpProtocolClient_
#define _SlmpProtocolClient_
#include <winsock2.h>
#include <stdlib.h>
#include <iostream>
#include <string>
// using System.Net.Socket;
class SlmpProtocolClient
{
public:
SlmpProtocolClient();
~SlmpProtocolClient();
public :
int Open() ;
int Close();
int ReadDRegister(short address, short len, unsigned short* short_array);
int ReadMBit(short adress, short len, unsigned short* short_array);
int WriteDRegister(short address, unsigned short short_value);
int WriteMBit(short address, unsigned short short_value);
void init2();
public :
bool Connected;
private:
WSADATA wsaData;
sockaddr_in sockAddr;
SOCKET sock;
std::string tipstr[20], tipstr2[20];
void GetHighLowByte(const short addrss, unsigned char& HByte, unsigned char& LByte);
};
#endif
#include "SlmpProtocolClient.h"
//#include <winsock2.h> //
SlmpProtocolClient::SlmpProtocolClient()
{
init2();
}
void SlmpProtocolClient::init2() {
tipstr[0] = "固定";
tipstr[1] = "----";
tipstr[2] = "----";
tipstr[3] = "----";
tipstr[4] = "----";
tipstr[5] = "----";
tipstr[6] = "固定";
tipstr[7] = "长度L";
tipstr[8] = "长度H";
tipstr[9] = " 结束代码L";
tipstr[10] = " 结束代码H";
tipstr[11] = " DXXXn-L";
tipstr[12] = " DXXXn-H";
tipstr[13] = " DXXXn+1-L";
tipstr[14] = " DXXXn+1-H";
tipstr[15] = " DXXXn+2-L";
tipstr[16] = " DXXXn+2-H";
tipstr2[0] = "固定";
tipstr2[1] = "----";
tipstr2[2] = "----";
tipstr2[3] = "----";
tipstr2[4] = "----";
tipstr2[5] = "----";
tipstr2[6] = "固定";
tipstr2[7] = "长度L";
tipstr2[8] = "长度H";
tipstr2[9] = " 结束代码L";
tipstr2[10] = " 结束代码H";
tipstr2[11] = " Mn | Mn + 1";
tipstr2[12] = " MXXX2n+2| MXXXn + 3";
tipstr2[13] = " MXXXn+4| MXXXn + 5";
}
SlmpProtocolClient::~SlmpProtocolClient()
{
Close();
}
int SlmpProtocolClient::Close()
{
closesocket(sock);
//终止使用 DLL
WSACleanup();
Connected=false;
return 0;
}
int SlmpProtocolClient::Open()
{
WSAStartup(MAKEWORD(2, 2), &wsaData);
//创建套接字
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//向服务器发起请求
memset(&sockAddr, 0, sizeof(sockAddr)); //每个字节都用0填充
sockAddr.sin_family = PF_INET;
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//sockAddr.sin_addr.s_addr = inet_addr("192.168.10.150");
sockAddr.sin_port = htons(1234);
// sockAddr.sin_port = htons(4999);
int ret=connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
if (ret==0) {
Connected=true;
}
return ret;
}
int SlmpProtocolClient::ReadDRegister(short address,short len, unsigned short * short_array)
{
SYSTEMTIME sys, sy2;
int a = 0;
char* str = new char[30];
while (a <1)
{
/* GetLocalTime(&sys);
std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;*/
//50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
str[0] = 0x50;//本行开始的7行固定
str[1] = 0x00;
str[2] = 0x00;
str[3] = 0xFF;
str[4] = 0xFF;
str[5] = 0x03;
str[6] = 0x00;//本行及以上固定
str[7] = 0x0C;//长度L字节
str[8] = 0x00;//长度H字节
str[9] = 0x10;//监视定时器L
str[10] = 0x00;//监视定时器H
str[11] = 0x01;//CMD-批量读取-L
str[12] = 0x04;//CMD-批量读取-H
str[13] = 0x00;//子CMD-L
str[14] = 0x00;//子CMD-H
//str[15] = 0x64;//开始地址-L
//str[16] = 0x00;//开始地址-Middle
//str[15] = 0x40;//开始地址-L
//str[16] = 0x01;//开始地址-Middle
unsigned char hByte, lByte;
GetHighLowByte(address, hByte, lByte);
str[15] = lByte;//开始地址-L
str[16] = hByte;//开始地址-Middle
str[17] = 0x00;//开始地址-H
str[18] = 0xA8;//表示D点
unsigned char hByte2, lByte2;
//str[19] = 0x03;//读取长度-L
//str[20] = 0x00;//读取长度-H
GetHighLowByte(len, hByte2, lByte2);
str[19] = lByte2;//读取长度-L
str[20] = hByte2;//读取长度-H
send(sock, str, 21, NULL);//读取D寄存器的发送报文的长度=21字节
// Sleep(1);
//接收服务器传回的数据
char szBuffer[MAXBYTE] = { 0 };
int m;
m=recv(sock, szBuffer, MAXBYTE, NULL);
//输出接收到的数据
//printf("Message form server: %s\n", szBuffer);
//printf("Message form server:\n ");
/* for (size_t i = 0; i < 13; i++)
{
if ((unsigned char)szBuffer[i] < 16)
{
printf("0%x ", (unsigned char)szBuffer[i]);
}
else
{
printf("%x ", (unsigned char)szBuffer[i]);
}
std::cout << "--" << tipstr[i] << std::endl;
}*/
//读出的放在数组里,以下按数组的索引号从0开始说明含义
// szBuffer[0]:0xD0,--固定
// szBuffer[1]:0X00,--固定
// szBuffer[2]:0X00,--固定
// szBuffer[3]:0XFF,--固定
// szBuffer[4]:0XFF,--固定
// szBuffer[5]:0X03,--固定
// szBuffer[6]:0X00,--固定
// szBuffer[7]:响应数据长L字节,如读1个字:0x04,2字:0x06,三个字0x08,依次类推
// szBuffer[8]:响应数据长高字节
// --------从szBuffer[9]开始计算长度-----
// szBuffer[9]:0x00,--结束代码,如不为0则异常
// szBuffer[10]:0x00,--结束代码,如不为0则异常
// szBuffer[11]:Dn的L字节
// szBuffer[12]:Dn的H字节
// szBuffer[13]:Dn+1的L字节
// szBuffer[14]:Dn+1的H字节
// szBuffer[15]:Dn+2的L字节
// szBuffer[16]:Dn+2的H字节
// 接收完成后,第一步先看结束代码是否为0,如为0,进行下一步,否则丢弃数据了
// 第二步判断响应数据长是否等于2*字数+2,如相等,进行下一步
// 第三步从szBuffer[11]开始取几个字的数据,注意高低字节,如Dn=256*szBuffer[12]+szBuffer[11]
short end_code= 256 * (unsigned char)szBuffer[10] + (unsigned char)szBuffer[9];
if (end_code != 0)
{
return -1;
}
short response_len= 256 * (unsigned char)szBuffer[8] + (unsigned char)szBuffer[7];
if (response_len!=(len*2+2))
{
return -1;
}
for (size_t i = 0; i < len; i++)
{
*(short_array+i) = 256 * (unsigned char)szBuffer[12+i*2] + (unsigned char)szBuffer[11+i*2];
//std::cout << "读到的第"<<i+1<<"个字=" << *short_array << std::endl;
}
/*std::cout << "读到的第1个字=" << 256 * (unsigned char)szBuffer[12] + (unsigned char)szBuffer[11] << std::endl;
std::cout << "第2个字=" << 256 * (unsigned char)szBuffer[14] + (unsigned char)szBuffer[13] << std::endl;
std::cout << "第3个字=" << 256 * szBuffer[16] + szBuffer[15] << std::endl;*/
/*GetLocalTime(&sy2);
std::cout << std::endl;
std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
std::cout << std::endl;*/
a++;
// Sleep(1);
}
delete[] str;
return 0;
}
int SlmpProtocolClient::WriteDRegister(short address, unsigned short short_value)
{
SYSTEMTIME sys, sy2;
int a = 0;
char* str = new char[30];
while (a < 1)
{
GetLocalTime(&sys);
std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;
//50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
str[0] = 0x50;//本行开始的7行固定
str[1] = 0x00;
str[2] = 0x00;
str[3] = 0xFF;
str[4] = 0xFF;
str[5] = 0x03;
str[6] = 0x00;//本行及以上固定
//str[7] = 0x12;//长度L字节--------写三个字0x12,写2个字,0x10,写一个字,0X0E
str[7] = 0x0E;//长度L字节--------写三个字0x12,写2个字,0x10,写一个字,0X0E
str[8] = 0x00;//长度H字节--------
str[9] = 0x10;//监视定时器L
str[10] = 0x00;//监视定时器H
str[11] = 0x01;//CMD-批量写-L
str[12] = 0x14;//CMD-批量写-H
str[13] = 0x00;//子CMD-L
str[14] = 0x00;//子CMD-H
//str[15] = 0x64;//开始地址-L-----变化
//str[16] = 0x00;//开始地址-Middle-----变化
unsigned char hByte, lByte;
GetHighLowByte(address, hByte, lByte);
str[15] = lByte;//开始地址-L
str[16] = hByte;//开始地址-Middle
str[17] = 0x00;//开始地址-H-----变化
str[18] = 0xA8;//表示D点
//str[19] = 0x03;//写入长度-L-------变化
str[19] = 0x01;//写入长度-L-------变化
str[20] = 0x00;//写入长度-H-------变化
//str[21] = 0x0C;//写入Dn-L-------变化
//str[22] = 0x00;//写入Dn-H-------变化
unsigned char hByte2, lByte2;
GetHighLowByte(short_value, hByte2, lByte2);
str[21] = lByte2;//读取长度-L
str[22] = hByte2;//读取长度-H
//str[23] = 0x0D;//写入Dn+1-L-------变化
//str[24] = 0x00;//写入Dn+1-H-------变化
//str[25] = 0x0E;//写入Dn+2-L-------变化
//str[26] = 0x00;//写入Dn+2-H-------变化
//"00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 01 00
//send(sock, str, strlen(str) + sizeof(char), NULL);
send(sock, str, 23, NULL);//-------------注意长度,写3个字:len=27,2个字:len=25,1个字:len=23
// Sleep(20);
//接收服务器传回的数据
char szBuffer[MAXBYTE] = { 0 };
recv(sock, szBuffer, MAXBYTE, NULL);
// PLC反馈: D0 00 00 FF FF 03 00 02 00 00 00 (00:14:55:188)
//输出接收到的数据
//printf("Message form server: %s\n", szBuffer);
if (0xD0 != (unsigned char)(szBuffer[0]) ) return 1;
if (0x02 != (unsigned char)szBuffer[7]) return 2;
if (0 != szBuffer[9]) return 3;
if (0 != szBuffer[10]) return 4;
/* GetLocalTime(&sy2);
std::cout << std::endl;
std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
std::cout << std::endl;*/
a++;
Sleep(1);
}
delete[] str;
return 0;
}
int SlmpProtocolClient::ReadMBit(short address, short len, unsigned short* short_array)
{
SYSTEMTIME sys, sy2;
int a = 0;
char* str = new char[30];
unsigned short temp;
unsigned short q;
unsigned short m;
unsigned short n;
unsigned short k;
m = len % 16;
n = (m==0)? (len - m) / 16:(len - m) / 16+1;
while (a < 1)
{
// GetLocalTime(&sys);
//std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;
//50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
str[0] = 0x50;//本行开始的7行固定
str[1] = 0x00;
str[2] = 0x00;
str[3] = 0xFF;
str[4] = 0xFF;
str[5] = 0x03;
str[6] = 0x00;//本行及以上固定
str[7] = 0x0C;//长度L字节
str[8] = 0x00;//长度H字节
str[9] = 0x10;//监视定时器L
str[10] = 0x00;//监视定时器H
str[11] = 0x01;//CMD-批量读取-L
str[12] = 0x04;//CMD-批量读取-H
str[13] = 0x00;//子CMD-L
str[14] = 0x00;//子CMD-H
//str[15] = 0x64;//开始地址-L---变化
//str[16] = 0x00;//开始地址-Middle---变化
unsigned char hByte, lByte;
GetHighLowByte(address, hByte, lByte);
str[15] = lByte;//开始地址-L
str[16] = hByte;//开始地址-Middle
str[17] = 0x00;//开始地址-H---变化
str[18] = 0x90;//表示M点
unsigned char hByte2, lByte2;
//str[19] = 0x03;//读取长度-L
//str[20] = 0x00;//读取长度-H
GetHighLowByte(n, hByte2, lByte2);
str[19] = lByte2;//读取长度-L
str[20] = hByte2;//读取长度-H
send(sock, str, 21, NULL);// /读取M的发送报文的长度=21字节
// Sleep(20);
//接收服务器传回的数据
char szBuffer[MAXBYTE] = { 0 };
recv(sock, szBuffer, MAXBYTE, NULL);
//输出接收到的数据
//printf("Message form server: %s\n", szBuffer);
/* printf("Message form server:\n ");
for (int i = 0; i < 13; i++)
{
if ((unsigned char)szBuffer[i] < 16)
{
printf("0%x ", (unsigned char)szBuffer[i]);
}
else
{
printf("%x ", (unsigned char)szBuffer[i]);
}
std::cout << tipstr2[i] << std::endl;
}
GetLocalTime(&sy2);*/
//读出的放在数组里,以下按数组的索引号从0开始说明含义
// szBuffer[0]:0xD0,--固定
// szBuffer[1]:0X00,--固定
// szBuffer[2]:0X00,--固定
// szBuffer[3]:0XFF,--固定
// szBuffer[4]:0XFF,--固定
// szBuffer[5]:0X03,--固定
// szBuffer[6]:0X00,--固定
// szBuffer[7]:响应数据长L字节,如读<=16:0x04,2字:0x06,三个字0x08,依次类推
// szBuffer[8]:响应数据长高字节
// --------从szBuffer[9]开始计算长度-----
// szBuffer[9]:0x00,--结束代码,如不为0则异常
// szBuffer[10]:0x00,--结束代码,如不为0则异常
// szBuffer[11]:Mn~M(n+7)
// szBuffer[12]:M(n+8)~M(n+15)
// 接收完成后,第一步先看结束代码是否为0,如为0,进行下一步,否则丢弃数据了
// 第二步判断响应数据长是否等于2*字数,如相等,进行下一步
// 第三步从szBuffer[11]开始取几个字的数据,注意高低字节,
//如Mn= szBuffer[12]& 0x01,Mn(n+1)= szBuffer[12]& 0x02,M(n+15)= szBuffer[13]& 0x80,Mn(n+1)= szBuffer[12]& 0x02,
short end_code = 256 * (unsigned char)szBuffer[10] + (unsigned char)szBuffer[9];
if (end_code != 0)
{
return -1;
}
short response_len = 256 * (unsigned char)szBuffer[8] + (unsigned char)szBuffer[7];
if (response_len != (n * 2 + 2))
{
return -1;
}
k = 0;
unsigned u;
for (size_t i = 0; i <n; i++)
{
temp = 256 * (unsigned char)szBuffer[12 + i * 2] + (unsigned char)szBuffer[11 + i * 2];
u = temp;
for (size_t j = 0; j< 16; j++)
{
short_array[k] =( ((u & 1) == 0) ? 0 : 1);
u = u >> 1;
k++;
if (k>=len)
{
break;
}
}
}
/* unsigned short temp = 256 * (unsigned char)szBuffer[12] + (unsigned char)szBuffer[11];
bool b;
for (int i = 0; i < 16; i++)
{
b = (temp == 1) ? true : false;
std::cout << "第" << i + 1 << "位:" << b << std::endl;
temp = temp >> 1;
}*/
/* std::cout << std::endl;
std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
std::cout << std::endl;*/
// delete[] str;
a++;
Sleep(1);
}
delete[] str;
return 0;
}
int SlmpProtocolClient::WriteMBit(short address, unsigned short short_value)
{
//SYSTEMTIME sys, sy2;
int a = 0;
char* str = new char[30];
while (a < 1)
{/*
GetLocalTime(&sys);
std::cout << sys.wSecond << ":" << sys.wMilliseconds << std::endl;*/
//50 00 00 FF FF 03 00 0C 00 10 00 01 04 00 00 64 00 00 A8 14 00
str[0] = 0x50;//本行开始的7行固定
str[1] = 0x00;
str[2] = 0x00;
str[3] = 0xFF;
str[4] = 0xFF;
str[5] = 0x03;
str[6] = 0x00;//本行及以上固定
str[7] = 0x0D;//长度L字节--------写三个字0x12,写2个字,0x10,写一个字,0X0E
str[8] = 0x00;//长度H字节--------
str[9] = 0x10;//监视定时器L
str[10] = 0x00;//监视定时器H
str[11] = 0x01;//CMD-批量写-L
str[12] = 0x14;//CMD-批量写-H
str[13] = 0x01;//子CMD-L
str[14] = 0x00;//子CMD-H
//str[15] = 0x64;//开始地址-L-----变化
//str[16] = 0x00;//开始地址-Middle-----变化
unsigned char hByte, lByte;
GetHighLowByte(address, hByte, lByte);
str[15] = lByte;//开始地址-L
str[16] = hByte;//开始地址-Middle
str[17] = 0x00;//开始地址-H-----变化
str[18] = 0x90;//表示M点
str[19] = 0x01;//写入长度-L-------变化
str[20] = 0x00;//写入长度-H-------变化
str[21] = ((short_value==0)?0x00:0x10);//写入Mn,M(n+1)-------变化
//str[22] = 0x00;//写入M(n+2),M(n+3)------变化
//"50 00 00 FF FF 03 00 0D 00 10 00 01 14 01 00 64 00 00 90 01 00 10
//send(sock, str, strlen(str) + sizeof(char), NULL);
send(sock, str, 22, NULL);//-------------注意长度,写3个字:len=27,2个字:len=25,1个字:len=23
// Sleep(20);
//接收服务器传回的数据
char szBuffer[MAXBYTE] = { 0 };
recv(sock, szBuffer, MAXBYTE, NULL);
//输出接收到的数据
//printf("Message form server: %s\n", szBuffer);
/* printf("Message form server:\n ");
for (size_t i = 0; i < 11; i++)
{
if ((unsigned char)szBuffer[i] < 16)
{
printf("0%x ", (unsigned char)szBuffer[i]);
}
else
{
printf("%x ", (unsigned char)szBuffer[i]);
}
std::cout << "--" << tipstr[i] << std::endl;
}
GetLocalTime(&sy2);
std::cout << std::endl;
std::cout << sy2.wSecond << ":" << sy2.wMilliseconds << std::endl;
std::cout << std::endl;*/
// PLC反馈: D0 00 00 FF FF 03 00 02 00 00 00 (00:14:55:188)
//输出接收到的数据
//printf("Message form server: %s\n", szBuffer);
if (0xD0 != (unsigned char)(szBuffer[0])) return 1;
if (0x02 != (unsigned char)szBuffer[7]) return 2;
if (0 != szBuffer[9]) return 3;
if (0 != szBuffer[10]) return 4;
a++;
Sleep(1);
}
delete[] str;
return 0;
}
void SlmpProtocolClient::GetHighLowByte(const short addrss, unsigned char & HByte, unsigned char & LByte)
{
LByte = addrss % 256;
HByte = (addrss - LByte) / 256;
}
三菱PLC slmp(mc)协议相关推荐
- 三菱PLC的MC协议配置说明
三菱PLC的MC协议配置说明 先说一下弱智的踩坑记录 详细配置过程 1.三菱Q02H CPU+QJ71E71-100以太网模块设置MC协议 1.1 PLC编程线连接与编程线驱动安装 1.2 PLC通讯 ...
- C#上位机与PLC通讯源码 C#与三菱PLC通讯MC协议
C#上位机与PLC通讯源码 C#与三菱PLC通讯MC协议 ID:696642996063203
- C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP /MC协议与三菱FX5U/Q系列PLC通讯
C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP /MC协议与三菱FX5U/Q系列PLC通讯 1.该程序可以与FX5U/Q系列PLC以太网通讯,根据3E帧报文写了一个类库,可以读写各种类型 ...
- C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP MC协议与三菱FX5U Q系列PLC通讯
C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP MC协议与三菱FX5U Q系列PLC通讯 1.该程序可以与FX5U Q系列PLC以太网通讯,根据3E帧报文写了一个类库,可以读写各种类型和 ...
- 三菱PLC的通讯协议
三菱PLC的通讯协议 测试FX3UPLC通讯报文 FX3U 扩展网口ENT-ADP MC协议 1E帧 #可以直接读取寄存器的地址,间接控制PLC执行 读取寄存器D100的地址 01 FF 0A 00 ...
- 三菱PLC以太网MC通讯协议模块
C.C++.C#与三菱PLC以太网通讯程序通讯,采用3E.4E的二进制模式. 软件模块高稳定性,数月数年运行无出错和问题. 性能指标: FX5U: 10000个点时间为30ms Q.LCPU 1000 ...
- C#与三菱PLC MC协议通信,Java与三菱PLC MC协议通信
三菱PLC的MC协议是一种常用的通信协议,用于实现三菱PLC与其他设备之间的通信.以下是一些关于MC协议的基本信息: 协议格式 MC协议的通信数据格式如下: 数据头 网络编号 PC编号 目标模块IO编 ...
- PLC程序实例一:MC协议定时进行网络触发
一.业务描述 1.PLC作为从站,等待主站连接 2.主站连接PLC后,对其某个地址进行寻址,并获取该地址内容 3.主站获取该内容后,与自身的指令进行对比 4.如果指令一致则执行业务,并把执行结果传输给 ...
- GX Works3 (四):FX5U作为服务端的以太网MC协议梯形图通信编程
一.通过通信协议进行通信 1.先根据操作文档进行基本操作 2.打开通讯协议支持功能并设置 3.Request\Normal response\Error response 全部可输入选项,输入D2进行 ...
最新文章
- 第二次冲刺团队进展报告七
- 【算法】划分数 动态规划
- AJAX省市县三级联动的实现
- python 线性回归模型_如何在Python中建立和训练线性和逻辑回归ML模型
- 配置linux登录超时命令,LINUX中 设置登录超时
- php计算一段时间工作日,PHP计算8小时工作日的一半
- Best MSI to EXE Convert tool
- 【马来西亚】娘惹的含义
- C双拼输入法使用说明
- Hive建表语句的中文注释乱码问题
- Windows操作系统免费下载地址(itellyou)
- 苹果支付Java后台总结
- 40款非常漂亮的免费下载 HTML5 CSS3 网站模板欣赏
- 大数据挖掘-使用频率top20中药材(收藏)
- PS各个工具的字母快捷键和英文全名
- 三种网线的RJ-45接头制作法图解(转)
- 小项目2——(未登录)指定微博账号基本公开信息的搜集
- Linux下的Chm文件阅读器
- 高级API 快速入门之第七章 本地模拟下载文件
- Docker入门实战大全终极版
热门文章
- Zed Shaw:程序员的常见健康问题
- qq群邮件html背景音乐,群发HTML格式邮件基础知识
- 架构 Varnish+Nginx+PHP(FastCGI)+MYSQL5+MemCache
- 阿里云获取token(亲测可用)
- 江苏计算机一级报名公告,江苏省2021年3月全国计算机等级考试报名公告发布
- Solidworks2020中零件图的材质无法正常显示的问题(只有在选中零件时材质才能正常显示)
- 校尉羽书飞瀚海,顺序表中增删改
- 连载32:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
- 白帽汇龙专:Web扫描器的架构变迁之路
- java测量麦克风音量_Android-使用mediarecorder类获取当前麦克风音量值