From 740d52c58564e0ae7463c3dfe5bd518fc1dfe0aa Mon Sep 17 00:00:00 2001 From: zcn1123 <2363211205@qq.com> Date: Tue, 1 Sep 2020 14:33:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=95=B4=E5=90=88=E5=8A=9F=E8=83=BD=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=97=A5=E5=BF=97=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=93=8D=E5=BA=94=E6=8A=A5?= =?UTF-8?q?=E6=96=87=E8=A7=A3=E6=9E=90=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Modbus_TCP/Modbus_TCP.vcxproj | 4 +- .../Modbus_TCP/Modbus_TCP_log.txt | 2 + .../Modbus_TCP/TCP_client.cpp | 62 +++++++++++++++---- Modbus_communication/Modbus_TCP/common.cpp | 44 ++++++++++++- Modbus_communication/Modbus_TCP/common.h | 4 +- 5 files changed, 102 insertions(+), 14 deletions(-) create mode 100644 Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt diff --git a/Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj b/Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj index d78837d..6d25ad6 100644 --- a/Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj +++ b/Modbus_communication/Modbus_TCP/Modbus_TCP.vcxproj @@ -43,7 +43,9 @@ Level3 Disabled - true + false + false + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true diff --git a/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt b/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt new file mode 100644 index 0000000..2cd8041 --- /dev/null +++ b/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt @@ -0,0 +1,2 @@ +2020-9-1 14:23:15 Send:00 00 00 00 00 06 09 01 00 00 00 09 +2020-9-1 14:23:17 Recv:00 00 00 00 00 05 10 01 02 FF 01 diff --git a/Modbus_communication/Modbus_TCP/TCP_client.cpp b/Modbus_communication/Modbus_TCP/TCP_client.cpp index d518220..94a8ead 100644 --- a/Modbus_communication/Modbus_TCP/TCP_client.cpp +++ b/Modbus_communication/Modbus_TCP/TCP_client.cpp @@ -101,10 +101,10 @@ SOCKET Init_client(string IP, unsigned int Port_number) cout << "尝试连接TCP从站失败" << endl; } cout << "连接TCP从站成功" << endl; - TIMEVAL timeout; - timeout.tv_sec = 2000; //ms - timeout.tv_usec = 0; //us - setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间 + //TIMEVAL timeout; + //timeout.tv_sec = 2000; //ms + //timeout.tv_usec = 0; //us + //setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间 return ClientSocket; } @@ -134,33 +134,69 @@ void Clear_recv_buf(SOCKET clientSocket) } } -void Printf_Coil_date(UINT8 *Response_Message) +void Printf_Coil_date(UINT8 *Response_Message, UINT8 *Request_Message) { - + printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]); + unsigned int temp1 = ((Request_Message[8] << 8) | Request_Message[9])+1; + unsigned int Number = ((Request_Message[10] << 8) | Request_Message[11]); + printf("线圈起始地址为%d \n",temp1); + unsigned int temp = temp1; + for (int i = 0; i < Response_Message[8]; i++) + { + unsigned int temp2 = temp + 7; + if (temp2 > temp1 + Number - 1) + temp2 = temp1 + Number - 1; + printf("线圈第%d --- %d的状态为:%02X \n", temp2, temp, Response_Message[9+i]); + temp = temp + 8; + } } -void Printf_Register_date(UINT8 *Response_Message) +void Printf_Register_date(UINT8 *Response_Message, UINT8 *Request_Message) { + printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]); + unsigned int temp1 = ((Request_Message[8] << 8) | Request_Message[9]) + 1; + unsigned int Number = ((Request_Message[10] << 8) | Request_Message[11]); + printf("寄存器起始地址为%d \n", temp1); + for (int i = 0; i < Response_Message[8]; i = i + 2) + { + printf("寄存器第%d的值为:%02X %02X \n", temp1++, Response_Message[9 + i], Response_Message[10+i]); + } } void Printf_Anomaly_date(UINT8 *Response_Message) { - + UINT8 a = Response_Message[8]; + printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]); + switch (a) + { + case 0x01: printf("%02X : 从站设备不支持此功能码",a); break; + case 0x02: printf("%02X : 指定的数据地址在从站设备中不存在",a); break; + case 0x03: printf("%02X : 指定的数据超过范围或者不允许使用",a); break; + case 0x04: printf("%02X : 从站设备处理响应的过程中,出现未知错误等",a); break; + default: printf("Unkown Other Error!!!!!"); + } } -k + bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, int Response_Message_len) { if (Response_Message[7] == Request_Message[7] + 0x80 && Response_Message_len == 9)//先处理异常响应 { - + Printf_Anomaly_date(Response_Message); return true; } else if (Response_Message[6] == Request_Message[6] && Response_Message_len - 5 == Response_Message[5]) //判断是否是正常响应帧 { - + if (Response_Message[7] == 0x01) + Printf_Coil_date(Response_Message, Request_Message); + if (Response_Message[7] == 0x03) + Printf_Register_date(Response_Message, Request_Message); + if (Response_Message[7] == 0x10) + printf("成功写入从站线圈%d个", ((Request_Message[10] << 8) | Request_Message[11])); + if (Response_Message[7] == 0x0F) + printf("成功写入从站寄存器%d个" ,((Request_Message[10] << 8) | Request_Message[11])); return true; } return false; @@ -197,18 +233,22 @@ bool Tcp_client(string IP, unsigned int Port_number) printf("%02x ", Request_Message[i]); } printf("\n"); + Log_Note(Request_Message, 1, Message_len); Clear_recv_buf(ClientSocket); send(ClientSocket, (char*)Request_Message, Message_len, 0); memset(Response_Message, 0, 260); int ret = recv(ClientSocket, (char*)Response_Message, 260, 0); if (ret > 0) { + Log_Note(Response_Message, 0, ret); printf("从站响应 :"); for (int i = 0; i < ret; i++) { printf("%02x ", Response_Message[i]); } printf("\n"); + if (Analysis_Response_Message(Response_Message, Request_Message, ret)) + printf("响应报文异常\n\n"); } else cout << "响应超时" << endl; diff --git a/Modbus_communication/Modbus_TCP/common.cpp b/Modbus_communication/Modbus_TCP/common.cpp index 8c5c83a..8a20b62 100644 --- a/Modbus_communication/Modbus_TCP/common.cpp +++ b/Modbus_communication/Modbus_TCP/common.cpp @@ -228,7 +228,7 @@ int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len) if (Write_date.length() == 0) return Message_len; const char *b = Write_date.c_str(); - for (int i = 0; i + 3 < Write_date.length(); i = i + 3) + for (unsigned int i = 0; i + 3 < Write_date.length(); i = i + 3) { sscanf_s(b + i, "%02X", (int *)(Message + Message_len)); Message_len++; @@ -257,3 +257,45 @@ int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations return HexStringtoByte(Message, Write_date, 12); } + +void Log_Note(UINT8 *Message, int flage, int Message_len) +{ + FILE *fp = NULL; + time_t timep; + struct tm *p; + time(&timep); + p = gmtime(&timep); + string Recv_str = to_string(1900 + p->tm_year) + "-" + to_string(1 + p->tm_mon) + "-" + to_string(p->tm_mday) + + " " + to_string(8 + p->tm_hour) + ":" + to_string(p->tm_min) + ":" + to_string(p->tm_sec) + " Recv:"; + string Send_str= to_string(1900 + p->tm_year) + "-" + to_string(1 + p->tm_mon) + "-" + to_string(p->tm_mday) + + " " + to_string(8 + p->tm_hour) + ":" + to_string(p->tm_min) + ":" + to_string(p->tm_sec) + " Send:"; + + /* 打开文件用于读写 */ + if ((fp = fopen("Modbus_TCP_log.txt", "a+")) == NULL) + { + printf("打开文件失败"); + return ; + } + + + if (flage == 1) + { + fwrite(Send_str.c_str(), Send_str.length(), 1, fp); + for (int i = 0; i < Message_len; i++) + { + fprintf(fp, "%02X ", Message[i]); + } + fprintf(fp,"\n"); + } + else + { + fwrite(Recv_str.c_str(), Recv_str.length(), 1, fp); + for (int i = 0; i < Message_len; i++) + { + fprintf(fp, "%02X ", Message[i]); + } + fprintf(fp, "\n"); + } + fclose(fp); + fp = NULL; +} diff --git a/Modbus_communication/Modbus_TCP/common.h b/Modbus_communication/Modbus_TCP/common.h index 5799a60..b3c237b 100644 --- a/Modbus_communication/Modbus_TCP/common.h +++ b/Modbus_communication/Modbus_TCP/common.h @@ -7,10 +7,11 @@ #include #include #include +#include #pragma comment(lib,"ws2_32.lib") using namespace std; -#define DEVICE_ID 0x10 //豸ID +#define DEVICE_ID 0x09 //豸ID @@ -23,6 +24,7 @@ string Input_Write_date(int Function_code, unsigned int Operations_Number); void Crate_MBAP(UINT8 *Message, int Function_code, unsigned int Operations_Number); int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len); int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations_Number, unsigned int Starting_address, string Write_date); +void Log_Note(UINT8 *Message, int flage, int Message_len); #endif \ No newline at end of file