//对于三菱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)协议相关推荐

  1. 三菱PLC的MC协议配置说明

    三菱PLC的MC协议配置说明 先说一下弱智的踩坑记录 详细配置过程 1.三菱Q02H CPU+QJ71E71-100以太网模块设置MC协议 1.1 PLC编程线连接与编程线驱动安装 1.2 PLC通讯 ...

  2. C#上位机与PLC通讯源码 C#与三菱PLC通讯MC协议

    C#上位机与PLC通讯源码 C#与三菱PLC通讯MC协议 ID:696642996063203

  3. C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP /MC协议与三菱FX5U/Q系列PLC通讯

    C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP /MC协议与三菱FX5U/Q系列PLC通讯 1.该程序可以与FX5U/Q系列PLC以太网通讯,根据3E帧报文写了一个类库,可以读写各种类型 ...

  4. C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP MC协议与三菱FX5U Q系列PLC通讯

    C#与三菱PLC以太网通讯程序上位机源码 通过3E帧SLMP MC协议与三菱FX5U Q系列PLC通讯 1.该程序可以与FX5U Q系列PLC以太网通讯,根据3E帧报文写了一个类库,可以读写各种类型和 ...

  5. 三菱PLC的通讯协议

    三菱PLC的通讯协议 测试FX3UPLC通讯报文 FX3U 扩展网口ENT-ADP MC协议 1E帧 #可以直接读取寄存器的地址,间接控制PLC执行 读取寄存器D100的地址 01 FF 0A 00 ...

  6. 三菱PLC以太网MC通讯协议模块

    C.C++.C#与三菱PLC以太网通讯程序通讯,采用3E.4E的二进制模式. 软件模块高稳定性,数月数年运行无出错和问题. 性能指标: FX5U: 10000个点时间为30ms Q.LCPU 1000 ...

  7. C#与三菱PLC MC协议通信,Java与三菱PLC MC协议通信

    三菱PLC的MC协议是一种常用的通信协议,用于实现三菱PLC与其他设备之间的通信.以下是一些关于MC协议的基本信息: 协议格式 MC协议的通信数据格式如下: 数据头 网络编号 PC编号 目标模块IO编 ...

  8. PLC程序实例一:MC协议定时进行网络触发

    一.业务描述 1.PLC作为从站,等待主站连接 2.主站连接PLC后,对其某个地址进行寻址,并获取该地址内容 3.主站获取该内容后,与自身的指令进行对比 4.如果指令一致则执行业务,并把执行结果传输给 ...

  9. GX Works3 (四):FX5U作为服务端的以太网MC协议梯形图通信编程

    一.通过通信协议进行通信 1.先根据操作文档进行基本操作 2.打开通讯协议支持功能并设置 3.Request\Normal response\Error response 全部可输入选项,输入D2进行 ...

最新文章

  1. 第二次冲刺团队进展报告七
  2. 【算法】划分数 动态规划
  3. AJAX省市县三级联动的实现
  4. python 线性回归模型_如何在Python中建立和训练线性和逻辑回归ML模型
  5. 配置linux登录超时命令,LINUX中 设置登录超时
  6. php计算一段时间工作日,PHP计算8小时工作日的一半
  7. Best MSI to EXE Convert tool
  8. 【马来西亚】娘惹的含义
  9. C双拼输入法使用说明
  10. Hive建表语句的中文注释乱码问题
  11. Windows操作系统免费下载地址(itellyou)
  12. 苹果支付Java后台总结
  13. 40款非常漂亮的免费下载 HTML5 CSS3 网站模板欣赏
  14. 大数据挖掘-使用频率top20中药材(收藏)
  15. PS各个工具的字母快捷键和英文全名
  16. 三种网线的RJ-45接头制作法图解(转)
  17. 小项目2——(未登录)指定微博账号基本公开信息的搜集
  18. Linux下的Chm文件阅读器
  19. 高级API 快速入门之第七章 本地模拟下载文件
  20. Docker入门实战大全终极版

热门文章

  1. Zed Shaw:程序员的常见健康问题
  2. qq群邮件html背景音乐,群发HTML格式邮件基础知识
  3. 架构 Varnish+Nginx+PHP(FastCGI)+MYSQL5+MemCache
  4. 阿里云获取token(亲测可用)
  5. 江苏计算机一级报名公告,江苏省2021年3月全国计算机等级考试报名公告发布
  6. Solidworks2020中零件图的材质无法正常显示的问题(只有在选中零件时材质才能正常显示)
  7. 校尉羽书飞瀚海,顺序表中增删改
  8. 连载32:软件体系设计新方向:数学抽象、设计模式、系统架构与方案设计(简化版)(袁晓河著)...
  9. 白帽汇龙专:Web扫描器的架构变迁之路
  10. java测量麦克风音量_Android-使用mediarecorder类获取当前麦克风音量值