|
|
@@ -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; |
|
|
|
} |