diff --git a/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt b/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt index 6f77bb6..dedd958 100644 --- a/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt +++ b/Modbus_communication/Modbus_TCP/Modbus_TCP_log.txt @@ -549,3 +549,23 @@ 2020-9-15 18:2:46 Recv:00 01 00 00 00 06 01 0F 08 00 00 01 2020-9-15 18:3:6 Send:00 02 00 00 00 09 01 10 00 00 00 01 02 00 55 2020-9-15 18:3:15 Recv:00 02 00 00 00 06 01 10 00 00 00 02 +2020-9-16 13:29:24 Send:00 00 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:30:39 Send:00 00 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:30:46 Send:00 01 00 00 00 06 01 03 00 00 00 01 +2020-9-16 13:31:8 Send:00 02 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:31:33 Send:00 03 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:37:20 Send:00 00 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:38:13 Send:00 00 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:38:16 Recv:11 11 11 01 01 01 01 01 01 +2020-9-16 13:38:24 Send:00 01 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:38:42 Recv:00 01 00 00 00 04 01 01 01 01 +2020-9-16 13:40:12 Send:00 02 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:40:37 Send:00 03 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:41:2 Send:00 04 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:41:5 Recv:00 01 00 00 00 04 01 01 01 01 +2020-9-16 13:41:18 Send:00 05 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:42:27 Send:00 00 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:44:1 Send:00 00 00 00 00 06 01 01 00 01 00 01 +2020-9-16 13:44:8 Send:00 01 00 00 00 06 01 01 00 00 00 02 +2020-9-16 13:44:36 Send:00 02 00 00 00 06 01 01 00 00 00 01 +2020-9-16 13:44:54 Send:00 03 00 00 00 09 01 10 00 00 00 01 02 00 00 diff --git a/Modbus_communication/Modbus_TCP/TCP_client.cpp b/Modbus_communication/Modbus_TCP/TCP_client.cpp index d664197..e37eb2b 100644 --- a/Modbus_communication/Modbus_TCP/TCP_client.cpp +++ b/Modbus_communication/Modbus_TCP/TCP_client.cpp @@ -26,13 +26,12 @@ bool InitSocket_Version(void) * 输出 : true IP地址合法 * false IP地址非法 *********************************************************************************************/ -bool Check_IP(string IP) +bool Check_IP(string ip) { int s[4]; - string ip = IP; if (ip.length() < 7 || ip.length() > 15) //长度判定 return false; - if (sscanf_s(IP.c_str(), "%d.%d.%d.%d", &s[0], &s[1], &s[2], &s[3]) != 4) //IPV4格式正确 + if (sscanf_s(ip.c_str(), "%d.%d.%d.%d", &s[0], &s[1], &s[2], &s[3]) != 4) //IPV4格式正确 { return false; } @@ -53,7 +52,7 @@ bool Check_IP(string IP) * *Port_number 端口号(1-65535) * 输出 : 无 *********************************************************************************************/ -void Input_IP(string& IP, unsigned int *Port_number) +void Input_IP(string& ip , unsigned int *port_number) { int i = 1; do @@ -65,8 +64,8 @@ void Input_IP(string& IP, unsigned int *Port_number) } else cout << "IP地址格式不正确,请重新输入从站IP:"; - cin >> IP; - } while (!Check_IP(IP)); + cin >> ip; + } while (!Check_IP(ip)); i = 1; cout << "IP地址输格式入正确,请输入从站端口号:"; @@ -74,42 +73,44 @@ void Input_IP(string& IP, unsigned int *Port_number) { if (i != 1) cout << "请重新输入从站端口号:"; - cin >> *Port_number; + cin >> *port_number; i = 0; - } while (*Port_number == 0 || *Port_number > 65535); //端口不能为0 ,端口号范围1---65535 + } while (*port_number == 0 || *port_number > 65535); //端口不能为0 ,端口号范围1---65535 } /********************************************************************************************* * 功能    : 初始化客户端 * 描述   : 根据终端输入从站IP地址和端口号连接对应的服务器,设置超时时间 -* 输入 : IP 地址 (IPV4) -* Port_number 端口号(1-65535) +* 输入 : 无 * 输出 : ClientSocket 连接成功的套接字 *********************************************************************************************/ -SOCKET Init_client() +SOCKET Init_Client() { - string IP; - unsigned int Port_number; - Input_IP(IP, &Port_number); if (InitSocket_Version() == 0) + { + printf("启动Socket服务失败,请检查Socket版本"); return INVALID_SOCKET; - SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0); - sockaddr_in Serversock_in; - Serversock_in.sin_addr.S_un.S_addr = inet_addr(IP.c_str()); - Serversock_in.sin_family = AF_INET; - Serversock_in.sin_port = htons(Port_number); - if(SOCKET_ERROR == connect(ClientSocket, (SOCKADDR*)&Serversock_in, sizeof(SOCKADDR))) + } + string ip_address; + unsigned int port_number; + Input_IP(ip_address, &port_number); + SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in serversock_in; + serversock_in.sin_addr.S_un.S_addr = inet_addr(ip_address.c_str()); + serversock_in.sin_family = AF_INET; + serversock_in.sin_port = htons(port_number); + if (SOCKET_ERROR == connect(clientSocket, (SOCKADDR*)&serversock_in, sizeof(SOCKADDR))) { cout << "尝试连接TCP从站失败" << endl; return INVALID_SOCKET; } cout << "连接TCP从站成功" << endl; TIMEVAL timeout; - timeout.tv_sec = 60000; //ms + timeout.tv_sec = 200; //ms timeout.tv_usec = 0; //us - setsockopt(ClientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间 - return ClientSocket; + setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间 + return clientSocket; } /********************************************************************************************* @@ -122,14 +123,14 @@ 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]); - unsigned int Number = ((Request_Message[10] << 8) | Request_Message[11]); + 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; + if (temp2 > temp1 + number - 1) + temp2 = temp1 + number - 1; printf("线圈%d --- %d的状态为:%02X \n", temp2, temp, Response_Message[9+i]); temp = temp + 8; } @@ -145,7 +146,6 @@ 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]); - 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) { @@ -161,53 +161,64 @@ void Printf_Register_date(UINT8 *Response_Message, UINT8 *Request_Message) *********************************************************************************************/ void Printf_Anomaly_date(UINT8 *Response_Message) { - UINT8 a = Response_Message[8]; + UINT8 anomaly_code = Response_Message[8]; printf("从站设备ID %02X 功能码为 %02X\n", Response_Message[6], Response_Message[7]); - switch (a) + switch (anomaly_code) { - case 0x01: printf("%02X : 从站设备不支持此功能码\n",a); break; - case 0x02: printf("%02X : 指定的数据地址在从站设备中不存在\n",a); break; - case 0x03: printf("%02X : 指定的数据超过范围或者不允许使用\n",a); break; - case 0x04: printf("%02X : 从站设备处理响应的过程中,出现未知错误等\n",a); break; + case 0x01: printf("%02X : 从站设备不支持此功能码\n", anomaly_code); break; + case 0x02: printf("%02X : 指定的数据地址在从站设备中不存在\n", anomaly_code); break; + case 0x03: printf("%02X : 指定的数据超过范围或者不允许使用\n", anomaly_code); break; + case 0x04: printf("%02X : 从站设备处理响应的过程中,出现未知错误等\n", anomaly_code); break; default: printf("Unkown Other Error!!!!!\n"); } } - - /********************************************************************************************* * 功能    : 检测响应报文长度 * 描述   : 对响应报文中存放长度字节进行判断和请求报文对比 * 输入 : Response_Message 响应报文 Request_Message 请求报文 Response_Message_len 接收到的数据长度 * 输出 : true 长度正常 false 长度异常 *********************************************************************************************/ -bool Check_Response_Message_len(UINT8 *Response_Message, UINT8 *Request_Message, int Response_Message_len) +bool Check_Response_Message_len(UINT8 *Response_Message, UINT8 *Request_Message, int response_message_len) { - if ((Response_Message_len - 6) != Response_Message[5]) + if ((response_message_len - 6) != Response_Message[5]) return false; - unsigned int Operations_Number = Request_Message[10] << 8 | Request_Message[11]; - unsigned int Respone_Len = Count_Respone_Len(Request_Message[7], Operations_Number); + unsigned int operations_Number = Request_Message[10] << 8 | Request_Message[11]; + unsigned int respone_Len = Count_Respone_Len(Request_Message[7], operations_Number); if (Request_Message[7] == 0x0F || Request_Message[7] == 0x10) - if (Response_Message_len != 12) + if (response_message_len != 12) return false; if (Request_Message[7] == 0x01 || Request_Message[7] == 0x03) { - if (Respone_Len + 9 != Response_Message_len) + if (respone_Len + 9 != response_message_len) return false; - if (Respone_Len != Response_Message[8]) + if (respone_Len != Response_Message[8]) return false; } return true; } + +bool Printf_Analysis_Outcome(UINT8 *Response_Message, UINT8 *Request_Message) +{ + switch (Response_Message[7]) + { + case 0x01:Printf_Coil_date(Response_Message, Request_Message); break; + case 0x03:Printf_Register_date(Response_Message, Request_Message); break; + case 0x0F:printf("成功写入从站线圈%d个\n", ((Request_Message[10] << 8) | Request_Message[11])); break; + case 0x10:printf("成功写入从站寄存器%d个\n", ((Request_Message[10] << 8) | Request_Message[11])); break; + default: return false; + } + return true; +} /********************************************************************************************* * 功能    : 判断响应报文是否可以正常解析 * 描述   : 通过长度和异常码等判定该响应报文是否可以解析 * 输入 : Response_Message 响应报文 Request_Message请求报文 Response_Message_len 响应报文长度 * 输出 : true可以正常解析 false 无法解析 *********************************************************************************************/ -bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, int Response_Message_len) +bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, int response_message_len) { - if (Response_Message_len < 9) + if (response_message_len < 9 || response_message_len > 260) return false; for (int i = 0; i < 7; i++) { @@ -221,7 +232,7 @@ bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, if (Response_Message[7] == Request_Message[7] + 0x80)//先处理异常响应 { - if (Response_Message_len == 9) + if (response_message_len == 9) { Printf_Anomaly_date(Response_Message); return true; @@ -239,161 +250,170 @@ bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, return false; } } - if (!Check_Response_Message_len(Response_Message, Request_Message, Response_Message_len)) + if (!Check_Response_Message_len(Response_Message, Request_Message, response_message_len)) return false; - if (Response_Message[7] == 0x01) - Printf_Coil_date(Response_Message, Request_Message); - else if (Response_Message[7] == 0x03) - Printf_Register_date(Response_Message, Request_Message); - else if (Response_Message[7] == 0x0F) - printf("成功写入从站线圈%d个\n", ((Request_Message[10] << 8) | Request_Message[11])); - else if (Response_Message[7] == 0x10) - printf("成功写入从站寄存器%d个\n", ((Request_Message[10] << 8) | Request_Message[11])); - else - return false; - return true; + //打印解析结果 + return Printf_Analysis_Outcome(Response_Message, Request_Message); } -void Clear_buf(SOCKET ClientSocket) +void Clear_buf(SOCKET clientSocket) { unsigned long bytesToRecv; char temp[500]; do { - - ioctlsocket(ClientSocket, FIONREAD, &bytesToRecv); + ioctlsocket(clientSocket, FIONREAD, &bytesToRecv); if (bytesToRecv != 0)//不等于0时进行清理操作 { if (bytesToRecv > 500) { - recv(ClientSocket, temp, 500, 0); + recv(clientSocket, temp, 500, 0); } else - recv(ClientSocket, temp, bytesToRecv, 0); + recv(clientSocket, temp, bytesToRecv, 0); } } while (bytesToRecv != 0); } +void Printf_Message(UINT8 *Message,int flage, int message_len) +{ + if (flage == 1) + printf("主站请求 :"); + else + printf("从站响应 :"); + for (int i = 0; i < message_len; i++) + { + printf("%02x ", Message[i]); + } + printf("\n"); + if (LOG_NOTE_SWITCH) + Log_Note(Message, flage, message_len); +} + +bool Send_date(SOCKET clientSocket, UINT8 *Request_Message, int request_message_len) +{ + Clear_buf(clientSocket); //清理缓冲区 + int status = send(clientSocket, (char*)Request_Message, request_message_len, 0); + if (status == (-1)) + { + return false; + } + Printf_Message(Request_Message, 1, request_message_len); + return true; +} + +bool Abnormal_Fisconnection(SOCKET *clientSocket) +{ + printf("连接异常,请检查连接状态。\n"); + printf("**************************** Press Enter To Contioun ****************************\n"); + getchar(); + system("cls"); + closesocket(*clientSocket); + WSACleanup(); + printf("是否重新连接服务器: 1 重新连接 0 关闭本软件"); + int flage = 0; + do + { + cin >> flage; + cin.clear(); + cin.sync(); + } while (!(flage == 0 || flage == 1)); + if (flage == 0) + return false; + system("cls"); + do + { + *clientSocket = Init_Client(); + } while (INVALID_SOCKET == *clientSocket); + system("cls"); + return true; +} + +int Recv_date(SOCKET clientSocket, UINT8 *Response_Message) +{ + int Response_Message_len = recv(clientSocket, (char*)Response_Message, 600, 0); + if (Response_Message_len > 0) + { + Printf_Message(Response_Message, 0, Response_Message_len); + return Response_Message_len; + } + return 0; +} + +bool Test_Connection_status(SOCKET clientSocket) +{ + TIMEVAL timeout; + timeout.tv_sec = 0; + timeout.tv_usec = 0; + fd_set reads; + FD_ZERO(&reads); + FD_SET(clientSocket, &reads); + if (select(0, &reads, 0, 0, &timeout)) + return false; + else + return true; +} /********************************************************************************************* * 功能    : 运行客户端 -* 描述   : 根据终端输入从站IP地址和端口号连接对应的服务器并且生成发送请求等待响应 +* 描述   : 初始化并且生成发送请求等待响应 * 输入 : 无 * 输出 : 无 *********************************************************************************************/ -int Tcp_client() +int Tcp_Client() { - SOCKET ClientSocket; - do - { - ClientSocket = Init_client(); - } while (INVALID_SOCKET == ClientSocket); + SOCKET clientSocket; UINT8 Request_Message[600]; + memset(Request_Message, 0, 600); UINT8 Response_Message[600]; - TIMEVAL timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 0; - fd_set reads; - UINT16 Transmission_Indicator = 0x00; + memset(Response_Message, 0, 600); + + do + { + clientSocket = Init_Client(); + } while (INVALID_SOCKET == clientSocket); + while (true) { - int Function_code = Input_Function_code(); - unsigned int Operations_Number = Input_Operations_Number(Function_code); - unsigned int Starting_address = Input_Starting_address(); - string Write_date = Input_Write_date(Function_code, Operations_Number); - int Request_Message_len = Crate_TCP_Message(Request_Message, Function_code, Operations_Number, Starting_address, Write_date); - Request_Message[0] = Transmission_Indicator >> 8; - Request_Message[1] = (UINT8)Transmission_Indicator; - printf("主站请求 :"); - for (int i = 0; i < Request_Message_len; i++) - { - printf("%02x ", Request_Message[i]); - } - printf("\n"); - Log_Note(Request_Message, 1, Request_Message_len); - Clear_buf(ClientSocket); //清理缓冲区 - int test = send(ClientSocket, (char*)Request_Message, Request_Message_len, 0); - if (Transmission_Indicator == 0xffff) - { - Transmission_Indicator = 0x00; - } - Transmission_Indicator++; - if (test == (-1)) + int function_code = Input_Function_code(); + unsigned int operations_Number = Input_Operations_number(function_code); + unsigned int starting_address = Input_Starting_address(); + string write_date = Input_Write_date(function_code, operations_Number); + //生成 + int request_message_len = Create_TCP_Message(Request_Message, function_code, operations_Number, starting_address, write_date); + + if (!Send_date(clientSocket, Request_Message, request_message_len)) //发送 { - printf("连接异常,请检查连接状态。\n"); - printf("**************************** Press Enter To Contioun ****************************\n"); - getchar(); - system("cls"); - closesocket(ClientSocket); - WSACleanup(); - printf("是否重新连接服务器: 1 重新连接 0 关闭本软件"); - int a = 0; - do - { - cin >> a; - cin.clear(); - cin.sync(); - } while (!(a == 0 || a == 1)); - if (a == 0) + if (Abnormal_Fisconnection(&clientSocket)) + continue; + else break; - system("cls"); - do - { - ClientSocket = Init_client(); - } while (INVALID_SOCKET == ClientSocket); - system("cls"); - continue; } - memset(Response_Message, 0, 600); - FD_ZERO(&reads); - FD_SET(ClientSocket, &reads); - int Response_Message_len = recv(ClientSocket, (char*)Response_Message, 600, 0); - if (Response_Message_len > 0) + + int Response_Message_len = Recv_date(clientSocket, Response_Message);//接收 + if (Response_Message_len) { - Log_Note(Response_Message, 0, Response_Message_len); - printf("从站响应 :"); - for (int i = 0; i < Response_Message_len; i++) - { - printf("%02x ", Response_Message[i]); - } - printf("\n"); if (!Analysis_Response_Message(Response_Message, Request_Message, Response_Message_len)) - printf("响应报文异常\n\n"); + printf("响应报文数据异常\n"); } - else if (select(0, &reads, 0, 0, &timeout)) + else { - printf("连接异常,请检查连接状态。\n"); - printf("**************************** Press Enter To Contioun ****************************\n"); - getchar(); - system("cls"); - closesocket(ClientSocket); - WSACleanup(); - printf("是否重新连接服务器: 1 重新连接 0 关闭本软件\n"); - int a = 0; - do - { - cin >> a; - cin.clear(); - cin.sync(); - } while (!(a == 0 || a == 1)); - if (a == 0) - break; - system("cls"); - do + if (!Test_Connection_status(clientSocket)) { - ClientSocket = Init_client(); - } while (INVALID_SOCKET == ClientSocket); - system("cls"); - continue; + if (Abnormal_Fisconnection(&clientSocket)) + continue; + else + break; + } + else + printf("响应超时\n"); } - else - cout << "响应超时" << endl; printf("**************************** Press Enter To Contioun ****************************\n"); getchar(); system("cls"); } //关闭套接字 - closesocket(ClientSocket); + closesocket(clientSocket); //关闭服务 WSACleanup(); return 0; diff --git a/Modbus_communication/Modbus_TCP/TCP_client.h b/Modbus_communication/Modbus_TCP/TCP_client.h index 4ed4271..995742e 100644 --- a/Modbus_communication/Modbus_TCP/TCP_client.h +++ b/Modbus_communication/Modbus_TCP/TCP_client.h @@ -4,12 +4,7 @@ #include "common.h" - -bool InitSocket_Version(void); -bool Check_IP(char* IP); -void Input_IP(string& IP, unsigned int *Port_number); -int Tcp_client(); -bool Analysis_Response_Message(UINT8 *Response_Message, UINT8 *Request_Message, int Response_Message_len); +int Tcp_Client(); #endif \ No newline at end of file diff --git a/Modbus_communication/Modbus_TCP/common.cpp b/Modbus_communication/Modbus_TCP/common.cpp index 1f0137c..858732d 100644 --- a/Modbus_communication/Modbus_TCP/common.cpp +++ b/Modbus_communication/Modbus_TCP/common.cpp @@ -1,5 +1,5 @@ #include "common.h" - +UINT16 Transmission_Indicator = 0x00; //事务号 /********************************************************************************************* * 功能    : 选择功能码 @@ -9,7 +9,7 @@ *********************************************************************************************/ int Input_Function_code(void) { - int Function_code; + int function_code; cin >> hex; int i = 1; printf("功能码 : 0x01 0x03 0x0F 0x10 \n"); @@ -23,22 +23,22 @@ int Input_Function_code(void) } else cout << "输入功能码错误,请重新选择的功能码"; - cin >> Function_code; + cin >> function_code; cin.clear(); cin.sync(); - } while (Function_code != 0x01 && Function_code != 0x03 && Function_code != 0x0F && Function_code != 0x10); - return Function_code; + } while (function_code != 0x01 && function_code != 0x03 && function_code != 0x0F && function_code != 0x10); + return function_code; } /********************************************************************************************* * 功能    : 输入操作起始地址码 * 描述   : 起始地址码,最大值65535 * 输入 : 无 -* 输出 : Starting_address 操作起始地址码 +* 输出 : starting_address 操作起始地址码 *********************************************************************************************/ unsigned int Input_Starting_address(void) { - unsigned int Starting_address; + unsigned int starting_address; int i = 1; cin >> dec; do @@ -50,22 +50,22 @@ unsigned int Input_Starting_address(void) } else cout << "请重新输入操作(十进制)起始地址"; - cin >> Starting_address; + cin >> starting_address; cin.clear(); cin.sync(); - } while (Starting_address > 65535 || Starting_address < 0); - return Starting_address; + } while (starting_address > 65535 || starting_address < 0); + return starting_address; } /********************************************************************************************* * 功能    : 输入操作数量 * 描述   : 操作数量,0x01 1-200 0x03 1-125 0x0xF 1-1968 0x10 1-123 -* 输入 : Function_code 选择的功能码类型 -* 输出 : Operations_Number 对应功能码类型的操作数量 +* 输入 : function_code 选择的功能码类型 +* 输出 : operations_Number 对应功能码类型的操作数量 *********************************************************************************************/ -unsigned int Input_Operations_Number(int Function_code) +unsigned int Input_Operations_number(int function_code) { - unsigned int Operations_Number; + unsigned int operations_Number; int i = 1; bool flage = true; printf(" 功能码 0x01 0x03 0x0F 0x10\n"); @@ -80,58 +80,58 @@ unsigned int Input_Operations_Number(int Function_code) } else cout << "请重新输入操作(十进制)数量"; - cin >> Operations_Number; + cin >> operations_Number; cin.clear(); cin.sync(); - if (Function_code == 0x01 && Operations_Number >= 1 && Operations_Number <= 65535) + if (function_code == 0x01 && operations_Number >= 1 && operations_Number <= 65535) flage = false; - if (Function_code == 0x03 && Operations_Number >= 1 && Operations_Number <= 65535) + if (function_code == 0x03 && operations_Number >= 1 && operations_Number <= 65535) flage = false; - if (Function_code == 0x0F && Operations_Number >= 1 && Operations_Number <= 65535) + if (function_code == 0x0F && operations_Number >= 1 && operations_Number <= 65535) flage = false; - if (Function_code == 0x10 && Operations_Number >= 1 && Operations_Number <= 65535) + if (function_code == 0x10 && operations_Number >= 1 && operations_Number <= 65535) flage = false; } while (flage); - return Operations_Number; + return operations_Number; } /********************************************************************************************* * 功能    : 检测写入数据 * 描述   : 检测写入数据格式是否正确 -* 输入 : Write_date 写入的数据 Write_date_number写入数据的组数 +* 输入 : write_date 写入的数据 write_date_number写入数据的组数 * 输出 : true 写入数据格式正确 * false 写入数据格式错误 *********************************************************************************************/ -bool Check_Write_date(string Write_date, int Write_date_number) +bool Check_Write_date(string write_date, int write_date_number) { - int Write_date_len = 2 * Write_date_number + Write_date_number - 1; - if (Write_date.length() != Write_date_len) + int write_date_len = 2 * write_date_number + write_date_number - 1; + if (write_date.length() != write_date_len) return false; - int Space_number = 0; - int j = -1; - for (unsigned int i = 0; i < Write_date.length(); i++) + int space_number = 0; + int temp = -1; + for (unsigned int i = 0; i < write_date.length(); i++) { - if (Write_date[i] == 0x20)//空格位置判定 + if (write_date[i] == 0x20)//空格位置判定 { - if (i - j == 3) + if (i - temp == 3) { - Space_number++; - j = i; + space_number++; + temp = i; continue; } else return false; } - if ((Write_date[i] >= 0x30 && Write_date[i] <= 0x39)) // 1-9 + if ((write_date[i] >= 0x30 && write_date[i] <= 0x39)) // 1-9 continue; - else if ((Write_date[i] >= 0x41 && Write_date[i] <= 0x5A)) //A-Z + else if ((write_date[i] >= 0x41 && write_date[i] <= 0x5A)) //A-Z continue; - else if ((Write_date[i] >= 0x61 && Write_date[i] <= 0x7A)) //a-z + else if ((write_date[i] >= 0x61 && write_date[i] <= 0x7A)) //a-z continue; else return false; } - if (Space_number != Write_date_number - 1) + if (space_number != write_date_number - 1) return false; return true; } @@ -140,23 +140,23 @@ bool Check_Write_date(string Write_date, int Write_date_number) /********************************************************************************************* * 功能    : 计算写入数据的字节数 * 描述   : 通过对应的功能码和操作数量计算对应的数据字节数 -* 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量 +* 输入 : function_code 选择的功能码类型 operations_Number对应功能码类型的操作数量 * 输出 : Write_date_number 写入数据的字节数 *********************************************************************************************/ -unsigned int Count_Write_date_number(int Function_code, unsigned int Operations_Number) +unsigned int Count_Write_date_number(int function_code, unsigned int operations_Number) { - unsigned int Write_date_number = 0; - if (Function_code == 0x01 || Function_code == 0x03) - return Write_date_number; - if (Function_code == 0x0F) //读线圈 + unsigned int write_date_number = 0; + if (function_code == 0x01 || function_code == 0x03) + return write_date_number; + if (function_code == 0x0F) //读线圈 { - Write_date_number = Operations_Number / 8; - if (Operations_Number % 8) - Write_date_number++; + write_date_number = function_code / 8; + if (operations_Number % 8) + write_date_number++; } - if (Function_code == 0x10) - Write_date_number = Operations_Number * 2; - return Write_date_number; + if (function_code == 0x10) + write_date_number = operations_Number * 2; + return write_date_number; } /********************************************************************************************* @@ -165,20 +165,20 @@ unsigned int Count_Write_date_number(int Function_code, unsigned int Operations_ * 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量 * 输出 : Respone_len 预期响应的数据字节数 *********************************************************************************************/ -unsigned int Count_Respone_Len(int Function_code, unsigned int Operations_Number) +unsigned int Count_Respone_Len(int function_code, unsigned int operations_Number) { - unsigned int Respone_len = 0; - if (Function_code == 0x0F|| Function_code == 0x10) - return Respone_len; - if (Function_code == 0x01) //读线圈 + unsigned int respone_len = 0; + if (function_code == 0x0F || function_code == 0x10) + return respone_len; + if (function_code == 0x01) //读线圈 { - Respone_len = Operations_Number / 8; - if (Operations_Number % 8) - Respone_len++; + respone_len = operations_Number / 8; + if (operations_Number % 8) + respone_len++; } - if (Function_code == 0x03) - Respone_len = Operations_Number * 2; - return Respone_len; + if (function_code == 0x03) + respone_len = operations_Number * 2; + return respone_len; } /********************************************************************************************* @@ -187,13 +187,13 @@ unsigned int Count_Respone_Len(int Function_code, unsigned int Operations_Number * 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量 * 输出 : Write_date 写入的数据 *********************************************************************************************/ -string Input_Write_date(int Function_code, unsigned int Operations_Number) +string Input_Write_date(int function_code, unsigned int operations_Number) { int i = 1; - string Write_date; - unsigned int Write_date_number = Count_Write_date_number(Function_code, Operations_Number); - if (Function_code == 0x01 || Function_code == 0x03) - return Write_date;//读线圈/寄存器不需要输入写入数据 + string write_date; + unsigned int write_date_number = Count_Write_date_number(function_code, operations_Number); + if (function_code == 0x01 || function_code == 0x03) + return write_date;//读线圈/寄存器不需要输入写入数据 printf("请输入N组写入数据(2位16进制为一组,空格间隔)例如:00 00 01 00 20 05\n"); do @@ -201,16 +201,16 @@ string Input_Write_date(int Function_code, unsigned int Operations_Number) if (i == 1) { i = 0; - printf("请输入%d组写入数据 :", Write_date_number); + printf("请输入%d组写入数据 :", write_date_number); } else - printf("请重新输入%d组写入数据 :", Write_date_number); - getline(cin, Write_date); + printf("请重新输入%d组写入数据 :", write_date_number); + getline(cin, write_date); cin.clear(); cin.sync(); - } while (!Check_Write_date(Write_date, Write_date_number)); + } while (!Check_Write_date(write_date, write_date_number)); - return Write_date; + return write_date; } /********************************************************************************************* @@ -229,15 +229,16 @@ string Input_Write_date(int Function_code, unsigned int Operations_Number) * 输入 : 无 * 输出 : MBAP报文头内容 *********************************************************************************************/ -void Crate_MBAP(UINT8 *Message, int Function_code, unsigned int Operations_Number) +void Create_MBAP(UINT8 *Message, int function_code, unsigned int operations_number) { - Message[0] = 0x00; - Message[1] = 0x00; - Message[2] = 0x00; + Message[0] = Transmission_Indicator >> 8;//事务号 + Message[1] = (UINT8)Transmission_Indicator; + Transmission_Indicator++; + Message[2] = 0x00; //Modbus协议标识 Message[3] = 0x00; - Message[4] = 0x00; - Message[5] = Count_Write_date_number(Function_code, Operations_Number) + 0x06; - if (Function_code == 0x0F || Function_code == 0x10) + Message[4] = 0x00;//后续字节长度 + Message[5] = Count_Write_date_number(function_code, operations_number) + 0x06; + if (function_code == 0x0F || function_code == 0x10)//0f/10功能码后续字节数多1 { Message[5] = Message[5] + 1; } @@ -251,20 +252,20 @@ void Crate_MBAP(UINT8 *Message, int Function_code, unsigned int Operations_Numbe * Message_len消息帧数组的起始位置 * 输出 : Message_len 消息帧的长度 *********************************************************************************************/ -int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len, int Function_code, unsigned int Operations_Number) +int HexStringtoByte(UINT8 *Message, string write_date, int message_len, int function_code, unsigned int operations_Number) { - if (Write_date.length() == 0) - return Message_len; - Message[Message_len] = Count_Write_date_number(Function_code, Operations_Number); - Message_len++; - const char *b = Write_date.c_str(); - for (unsigned int i = 0; i + 3 < Write_date.length(); i = i + 3) + if (write_date.length() == 0) + return message_len; + Message[message_len] = Count_Write_date_number(function_code, operations_Number); + message_len++; + const char *b = write_date.c_str(); + for (unsigned int i = 0; i + 3 < write_date.length(); i = i + 3) { - sscanf_s(b + i, "%02X", (int *)(Message + Message_len)); - Message_len++; + sscanf_s(b + i, "%02X", (int *)(Message + message_len)); + message_len++; } - sscanf_s(b + Write_date.length() - 2, "%02X", (int *)(Message + Message_len)); - return ++Message_len; + sscanf_s(b + write_date.length() - 2, "%02X", (int *)(Message + message_len)); + return ++message_len; } /********************************************************************************************* @@ -274,17 +275,17 @@ int HexStringtoByte(UINT8 *Message, string Write_date, int Message_len, int Func * Function_code 功能码 Operations_Number 操作数量 Starting_address起始地址 * 输出 : 消息帧的总长度 *********************************************************************************************/ -int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations_Number, unsigned int Starting_address, string Write_date) +int Create_TCP_Message(UINT8 *Message, int function_code, unsigned int operations_Number, unsigned int starting_address, string write_date) { - Crate_MBAP(Message, Function_code, Operations_Number); - Message[7] = Function_code;//功能码 - Message[8] = Starting_address >> 8;//起始地址H - Message[9] = Starting_address;//起始地址L - Message[10] = Operations_Number >> 8;//操作数量H - Message[11] = Operations_Number;//操作数量L + Create_MBAP(Message, function_code, operations_Number); + Message[7] = function_code;//功能码 + Message[8] = starting_address >> 8;//起始地址H + Message[9] = starting_address;//起始地址L + Message[10] = operations_Number >> 8;//操作数量H + Message[11] = operations_Number;//操作数量L - return HexStringtoByte(Message, Write_date, 12, Function_code, Operations_Number); + return HexStringtoByte(Message, write_date, 12, function_code, operations_Number); } @@ -296,16 +297,16 @@ int Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations * 输出 : 无 *********************************************************************************************/ -void Log_Note(UINT8 *Message, int flage, int Message_len) +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) + 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) + 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:"; /* 打开文件用于读写 */ @@ -314,11 +315,10 @@ void Log_Note(UINT8 *Message, int flage, int Message_len) printf("打开文件失败"); return ; } - if (flage == 1) { - fwrite(Send_str.c_str(), Send_str.length(), 1, fp); - for (int i = 0; i < Message_len; i++) + fwrite(send_str.c_str(), send_str.length(), 1, fp); + for (int i = 0; i < message_len; i++) { fprintf(fp, "%02X ", Message[i]); } @@ -326,8 +326,8 @@ void Log_Note(UINT8 *Message, int flage, int Message_len) } else { - fwrite(Recv_str.c_str(), Recv_str.length(), 1, fp); - for (int i = 0; i < Message_len; i++) + fwrite(recv_str.c_str(), recv_str.length(), 1, fp); + for (int i = 0; i < message_len; i++) { fprintf(fp, "%02X ", Message[i]); } diff --git a/Modbus_communication/Modbus_TCP/common.h b/Modbus_communication/Modbus_TCP/common.h index c6e0288..7dd2055 100644 --- a/Modbus_communication/Modbus_TCP/common.h +++ b/Modbus_communication/Modbus_TCP/common.h @@ -12,20 +12,18 @@ using namespace std; #define DEVICE_ID 0x01 //豸ID +#define LOG_NOTE_SWITCH 1 //־¼λ int Input_Function_code(void); unsigned int Input_Starting_address(void); -unsigned int Input_Operations_Number(int Function_code); -bool Check_Write_date(string Write_date, int Write_date_number); -unsigned int Count_Write_date_number(int Function_code, unsigned int Operations_Number); -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 Function_code, unsigned int Operations_Number); -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); -unsigned int Count_Respone_Len(int Function_code, unsigned int Operations_Number); +unsigned int Input_Operations_number(int function_code); +unsigned int Count_Write_date_number(int function_code, unsigned int operations_Number); +string Input_Write_date(int function_code, unsigned int operations_Number); +int Create_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); +unsigned int Count_Respone_Len(int function_code, unsigned int operations_Number); #endif \ No newline at end of file diff --git a/Modbus_communication/Modbus_TCP/main.cpp b/Modbus_communication/Modbus_TCP/main.cpp index b2f924f..6b26f0a 100644 --- a/Modbus_communication/Modbus_TCP/main.cpp +++ b/Modbus_communication/Modbus_TCP/main.cpp @@ -2,7 +2,7 @@ int main() { - Tcp_client(); + Tcp_Client(); getchar(); return 0; } \ No newline at end of file