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