196 lines
5.4 KiB

  1. #include "TCP_client.h"
  2. /*********************************************************************************************
  3. * 功能    : IP地址有效性检测
  4. * 描述   : 检测输入的IP地址是否合法
  5. * 输入 : IP 输入的IP地址
  6. * 输出 : true IP地址合法
  7. * false IP地址非法
  8. *********************************************************************************************/
  9. bool Check_IP(string ip)
  10. {
  11. int s[4];
  12. if (ip.length() < 7 || ip.length() > 15) //长度判定
  13. return false;
  14. if (sscanf_s(ip.c_str(), "%d.%d.%d.%d", &s[0], &s[1], &s[2], &s[3]) != 4) //IPV4格式正确
  15. {
  16. return false;
  17. }
  18. string newip = to_string(s[0]) + "." + to_string(s[1]) + "." + to_string(s[2]) + "." + to_string(s[3]);
  19. if (ip != newip) //前导0
  20. return false;
  21. if ((s[0] & 0xffffff00) || (s[1] & 0xffffff00) || (s[2] & 0xffffff00) || (s[3] & 0xffffff00)) //判断每一段大小是否符合要求
  22. {
  23. return false;
  24. }
  25. return true;
  26. }
  27. /*********************************************************************************************
  28. * 功能    : 获取从站IP地址和端口号
  29. * 描述   : 终端输入从站IP地址和端口号
  30. * 输入 : IP 地址 (IPV4)
  31. * *Port_number 端口号(1-65535)
  32. * 输出 : 无
  33. *********************************************************************************************/
  34. void Input_IP(string& ip, unsigned int *port_number)
  35. {
  36. int i = 1;
  37. do
  38. {
  39. if (i == 1)
  40. {
  41. cout << "请输入从站IP:";
  42. i = 0;
  43. }
  44. else
  45. cout << "IP地址格式不正确,请重新输入从站IP:";
  46. cin >> ip;
  47. } while (!Check_IP(ip));
  48. i = 1;
  49. cout << "IP地址输格式入正确,请输入从站端口号:";
  50. do
  51. {
  52. if (i != 1)
  53. cout << "请重新输入从站端口号:";
  54. cin >> *port_number;
  55. i = 0;
  56. } while (*port_number == 0 || *port_number > 65535); //端口不能为0 ,端口号范围1---65535
  57. }
  58. /*********************************************************************************************
  59. * 功能    : socket版本
  60. * 描述   : 启动socket服务
  61. * 输入 : 无
  62. * 输出 : true 启动成功
  63. * false 启动失败
  64. *********************************************************************************************/
  65. bool InitSocket_Version(void)
  66. {
  67. WORD sockVersion = MAKEWORD(2, 2);//使用winsocket2.2版本
  68. WSADATA wsaData;
  69. if (WSAStartup(sockVersion, &wsaData) != 0)
  70. {
  71. return false;
  72. }
  73. return true;
  74. }
  75. /*********************************************************************************************
  76. * 功能    : 初始化客户端
  77. * 描述   : 根据终端输入从站IP地址和端口号连接对应的服务器,设置超时时间
  78. * 输入 : 无
  79. * 输出 : ClientSocket 连接成功的套接字
  80. *********************************************************************************************/
  81. SOCKET Init_Client(void)
  82. {
  83. if (InitSocket_Version() == 0)
  84. {
  85. printf("启动Socket服务失败,请检查Socket版本");
  86. return INVALID_SOCKET;
  87. }
  88. string ip_address;
  89. unsigned int port_number;
  90. Input_IP(ip_address, &port_number);
  91. SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
  92. sockaddr_in serversock_in;
  93. serversock_in.sin_addr.S_un.S_addr = inet_addr(ip_address.c_str());
  94. serversock_in.sin_family = AF_INET;
  95. serversock_in.sin_port = htons(port_number);
  96. if (SOCKET_ERROR == connect(clientSocket, (SOCKADDR*)&serversock_in, sizeof(SOCKADDR)))
  97. {
  98. cout << "尝试连接TCP从站失败" << endl;
  99. return INVALID_SOCKET;
  100. }
  101. cout << "连接TCP从站成功" << endl;
  102. TIMEVAL timeout;
  103. timeout.tv_sec = 200; //ms
  104. timeout.tv_usec = 0; //us
  105. setsockopt(clientSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(struct timeval));//设置接收超时时间
  106. return clientSocket;
  107. }
  108. void Clear_buf(SOCKET clientSocket)
  109. {
  110. unsigned long bytesToRecv;
  111. char temp[500];
  112. do
  113. {
  114. ioctlsocket(clientSocket, FIONREAD, &bytesToRecv);
  115. if (bytesToRecv != 0)//不等于0时进行清理操作
  116. {
  117. if (bytesToRecv > 500)
  118. {
  119. recv(clientSocket, temp, 500, 0);
  120. }
  121. else
  122. recv(clientSocket, temp, bytesToRecv, 0);
  123. }
  124. } while (bytesToRecv != 0);
  125. }
  126. bool Send_date(SOCKET clientSocket, UINT8 *Request_Message, int request_message_len)
  127. {
  128. Clear_buf(clientSocket); //清理缓冲区
  129. int status = send(clientSocket, (char*)Request_Message, request_message_len, 0);
  130. if (status == (-1))
  131. {
  132. return false;
  133. }
  134. return true;
  135. }
  136. bool Abnormal_Connection(SOCKET *clientSocket)
  137. {
  138. printf("连接异常,请检查连接状态。\n");
  139. printf("**************************** Press Enter To Contioun ****************************\n");
  140. getchar();
  141. system("cls");
  142. closesocket(*clientSocket);
  143. WSACleanup();
  144. printf("是否重新连接服务器: 1 重新连接 0 关闭本软件\n");
  145. int flage = 0;
  146. do
  147. {
  148. cin >> flage;
  149. cin.clear();
  150. cin.sync();
  151. } while (!(flage == 0 || flage == 1));
  152. if (flage == 0)
  153. return false;
  154. system("cls");
  155. do
  156. {
  157. *clientSocket = Init_Client();
  158. } while (INVALID_SOCKET == *clientSocket);
  159. system("cls");
  160. return true;
  161. }
  162. int Recv_date(SOCKET clientSocket, UINT8 *Response_Message)
  163. {
  164. int Response_Message_len = recv(clientSocket, (char*)Response_Message, 600, 0);
  165. if (Response_Message_len > 0)
  166. {
  167. return Response_Message_len;
  168. }
  169. return 0;
  170. }
  171. bool Test_Connection_status(SOCKET clientSocket)
  172. {
  173. TIMEVAL timeout;
  174. timeout.tv_sec = 0;
  175. timeout.tv_usec = 0;
  176. fd_set reads;
  177. FD_ZERO(&reads);
  178. FD_SET(clientSocket, &reads);
  179. if (select(0, &reads, 0, 0, &timeout))
  180. return false;
  181. else
  182. return true;
  183. }