Sfoglia il codice sorgente

整合功能模块

Modbus_TCP
zcn1123 4 anni fa
parent
commit
78ee81c1ad
5 ha cambiato i file con 223 aggiunte e 108 eliminazioni
  1. +196
    -16
      Modbus_communication/Modbus_TCP/TCP_client.cpp
  2. +7
    -1
      Modbus_communication/Modbus_TCP/TCP_client.h
  3. +6
    -80
      Modbus_communication/Modbus_TCP/common.cpp
  4. +10
    -3
      Modbus_communication/Modbus_TCP/common.h
  5. +4
    -8
      Modbus_communication/Modbus_TCP/main.cpp

+ 196
- 16
Modbus_communication/Modbus_TCP/TCP_client.cpp Vedi File

@@ -1,5 +1,92 @@
#include "TCP_client.h"
#include "TCP_client.h"


/*********************************************************************************************
* 功能    : 检测socket版本
* �述   : 检测socket版本是�一致
* 输入 : 无
* 输出 : true socket版本一致
* false socket版本�一致
*********************************************************************************************/
bool InitSocket_Version(void)
{
WORD sockVersion = MAKEWORD(2, 2);//使用winsocket2.2版本
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return false;
}
return true;
}

/*********************************************************************************************
* 功能    : IP地�有效性检测
* �述   : 检测输入的IP地�是��法
* 输入 : IP 输入的IP地�
* 输出 : true IP地��法
* false 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格�正确
{
return false;
}
string newip = to_string(s[0]) + "." + to_string(s[1]) + "." + to_string(s[2]) + "." + to_string(s[3]);
if (ip != newip) //�导0
return false;
if ((s[0] & 0xffffff00) || (s[1] & 0xffffff00) || (s[2] & 0xffffff00) || (s[3] & 0xffffff00)) //判断�一段大�是�符��求
{
return false;
}
return true;
}

/*********************************************************************************************
* 功能    : 获�从站IP地�和端��
* �述   : 终端输入从站IP地�和端��
* 输入 : IP 地� (IPV4)
* *Port_number 端��(1-65535)
* 输出 : 无
*********************************************************************************************/
void Input_IP(string& IP, unsigned int *Port_number)
{
int i = 1;
do
{
if (i == 1)
{
cout << "请输入从站IP:";
i = 0;
}
else
cout << "IP地�格��正确,请�新输入从站IP:";
cin >> IP;
} while (!Check_IP(IP));

i = 1;
cout << "IP地�输格�入正确,请输入从站端��:";
do
{
if (i != 1)
cout << "请�新输入从站端��:";
cin >> *Port_number;
i = 0;
} while (*Port_number == 0 || *Port_number > 65535); //端��能为0 ,端��范围0---65535

}

/*********************************************************************************************
* 功能    : �始化客户端
* �述   : 根�终端输入从站IP地�和端��连接对应的�务器,设置超时时间
* 输入 : IP 地� (IPV4)
* Port_number 端��(1-65535)
* 输出 : ClientSocket 连接�功的套接字
*********************************************************************************************/
SOCKET Init_client(string IP, unsigned int Port_number)
{
if (InitSocket_Version() == 0)
@@ -11,31 +98,124 @@ SOCKET Init_client(string IP, unsigned int Port_number)
Serversock_in.sin_port = htons(Port_number);
while (SOCKET_ERROR == connect(ClientSocket, (SOCKADDR*)&Serversock_in, sizeof(SOCKADDR)))
{
cout << "³¢ÊÔÁ¬½ÓTCP´Óվʧ°Ü" << endl;
cout << "�试连接TCP从站失败" << endl;
}
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));//设置接收超时时间
return ClientSocket;
}

int Tcp_client(string IP, unsigned int Port_number)
/*********************************************************************************************
* 功能    : 清除接收缓冲区中的数�
* �述   : �一次��请求�清空缓存区数�
* 输入 : ClientSocket 客户端套接字
* 输出 : 无
*********************************************************************************************/
void Clear_recv_buf(SOCKET clientSocket)
{
SOCKET clientSocket = Init_client(IP, Port_number);
if (INVALID_SOCKET == clientSocket)
struct timeval tmOut;
tmOut.tv_sec = 0;
tmOut.tv_usec = 0;
fd_set fds;
FD_ZERO(&fds);
FD_SET(clientSocket, &fds);
int nRet;
char tmp[2];
memset(tmp, 0, sizeof(tmp));
while (1)
{
cout << "³õʼ»¯Ö÷վʧ°Ü" << endl;
nRet = select(FD_SETSIZE, &fds, NULL, NULL, &tmOut);
if (nRet == 0)
break;
recv(clientSocket, tmp, 1, 0);
}
}

void Printf_Coil_date(UINT8 *Response_Message)
{

}

void Printf_Register_date(UINT8 *Response_Message)
{

}
void Printf_Anomaly_date(UINT8 *Response_Message)
{

}

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)//先处�异常�应
{

return true;
}
else if (Response_Message[6] == Request_Message[6] && Response_Message_len - 5 == Response_Message[5]) //判断是�是正常�应帧
{

return true;
}
return false;
}

/*********************************************************************************************
* 功能    : �行客户端
* �述   : 根�终端输入从站IP地�和端��连接对应的�务器并且生���请求等待�应
* 输入 : IP 地� (IPV4)
* Port_number 端��(1-65535)
* 输出 : false 执行出错 true 执行�功
*********************************************************************************************/
bool Tcp_client(string IP, unsigned int Port_number)
{
SOCKET ClientSocket = Init_client(IP, Port_number);
if (INVALID_SOCKET == ClientSocket)
{
cout << "�始化主站失败" << endl;
return false;
}
UINT8 Request_Message[260];
UINT8 Response_Message[260];
while (true)
{
char receiveBuf[260];
memset(receiveBuf, 0, 100);
recv(clientSocket, receiveBuf, 100, 0);
printf("%s\n", receiveBuf);
send(clientSocket, "hello,this is client", strlen("hello,this is client") + 1, 0);

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 Message_len = Crate_TCP_Message(Request_Message, Function_code, Operations_Number, Starting_address, Write_date);
printf("主站请求 :");
for (int i = 0; i < Message_len; i++)
{
printf("%02x ", Request_Message[i]);
}
printf("\n");
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)
{
printf("从站�应 :");
for (int i = 0; i < ret; i++)
{
printf("%02x ", Response_Message[i]);
}
printf("\n");
}
else
cout << "�应超时" << endl;
}
//¹Ø±ÕÌ×½Ó×Ö
closesocket(clientSocket);
//¹Ø±Õ·þÎñ
//关闭套接字
closesocket(ClientSocket);
//关闭�务
WSACleanup();
return false;
return true;
}

+ 7
- 1
Modbus_communication/Modbus_TCP/TCP_client.h Vedi File

@@ -3,6 +3,12 @@

#include "common.h"

int Tcp_client(string IP, unsigned int Port_number);


bool InitSocket_Version(void);
bool Check_IP(char* IP);
void Input_IP(string& IP, unsigned int *Port_number);
bool Tcp_client(string IP, unsigned int Port_number);


#endif

+ 6
- 80
Modbus_communication/Modbus_TCP/common.cpp Vedi File

@@ -1,83 +1,5 @@
#include "common.h"

/*********************************************************************************************
* 功能    : 检测socket版本
* 描述   : 检测socket版本是否一致
* 输入 : 无
* 输出 : true socket版本一致
* false socket版本不一致
*********************************************************************************************/
bool InitSocket_Version(void)
{
WORD sockVersion = MAKEWORD(2, 2);//使用winsocket2.2版本
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return false;
}
return true;
}

/*********************************************************************************************
* 功能    : IP地址有效性检测
* 描述   : 检测输入的IP地址是否合法
* 输入 : IP 输入的IP地址
* 输出 : true IP地址合法
* false 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格式正确
{
return false;
}
string newip = to_string(s[0]) + "." + to_string(s[1]) + "." + to_string(s[2]) + "." + to_string(s[3]);
if (ip != newip) //前导0
return false;
if ((s[0] & 0xffffff00) || (s[1] & 0xffffff00) || (s[2] & 0xffffff00) || (s[3] & 0xffffff00)) //判断每一段大小是否符合要求
{
return false;
}
return true;
}

/*********************************************************************************************
* 功能    : 获取从站IP地址和端口号
* 描述   : 终端输入从站IP地址和端口号
* 输入 : IP 地址 (IPV4)
* *Port_number 端口号(1-65535)
* 输出 : 无
*********************************************************************************************/
void Input_IP(string& IP, unsigned int *Port_number)
{
int i = 1;
do
{
if (i == 1)
{
cout << "请输入从站IP:";
i = 0;
}
else
cout << "IP地址格式不正确,请重新输入从站IP:";
cin >> IP;
} while (!Check_IP(IP));

i = 1;
cout << "IP地址输格式入正确,请输入从站端口号:";
do
{
if (i != 1)
cout << "请重新输入从站端口号:";
cin >> *Port_number;
i = 0;
} while (*Port_number == 0 || *Port_number > 65535); //端口不能为0 ,端口号范围0---65535

}

/*********************************************************************************************
* 功能    : 选择功能码
@@ -118,7 +40,7 @@ unsigned int Input_Starting_address(void)
{
unsigned int Starting_address;
int i = 1;
printf("请输入操作(十进制)起始地址 \n");
cin >> dec;
do
{
if (i == 1)
@@ -148,6 +70,7 @@ unsigned int Input_Operations_Number(int Function_code)
bool flage = true;
printf(" 功能码 0x01 0x03 0x0F 0x10\n");
printf("操作数量 1-2000 1-125 1-1968 1-123\n");
cin >> dec;
do
{
if (i == 1)
@@ -194,6 +117,7 @@ bool Check_Write_date(string Write_date, int Write_date_number)
{
Space_number++;
j = i;
continue;
}
else
return false;
@@ -239,7 +163,7 @@ unsigned int Count_Write_date_number(int Function_code, unsigned int Operations_
* 输入 : Function_code 选择的功能码类型 Operations_Number对应功能码类型的操作数量
* 输出 : Write_date 写入的数据
*********************************************************************************************/
string 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;
@@ -301,6 +225,8 @@ void Crate_MBAP(UINT8 *Message, int Function_code, unsigned int Operations_Numbe
*********************************************************************************************/
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)
{


+ 10
- 3
Modbus_communication/Modbus_TCP/common.h Vedi File

@@ -14,8 +14,15 @@ using namespace std;



bool Check_IP(char* IP);
bool InitSocket_Version(void);
void Input_IP(string& IP, unsigned int *Port_number);
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 Crate_TCP_Message(UINT8 *Message, int Function_code, unsigned int Operations_Number, unsigned int Starting_address, string Write_date);


#endif

+ 4
- 8
Modbus_communication/Modbus_TCP/main.cpp Vedi File

@@ -1,15 +1,11 @@
#include "main.h"

#define DEVICE_ID 0x10

int main()
{
UINT8 Message[260];
int Function_code = 0x10;
unsigned int Operations_Number = 5;
unsigned int Starting_address = 13;
string a = "1F 00 01 02 03 04 05 06 07 06";
string IP;
unsigned int Port;
Input_IP(IP,&Port);
Tcp_client(IP,Port);
getchar();
return 0;
}

Caricamento…
Annulla
Salva