#include #include #include._tcp client 模式">
当前位置:   article > 正文

TCP模式的一个服务器和多个客户端通信_tcp client 模式

tcp client 模式

 服务端

  1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <WinSock2.h>
  4. #include <WS2tcpip.h>
  5. #pragma comment(lib,"ws2_32.lib")
  6. #include <stdio.h>
  7. #include <Windows.h>
  8. #include <conio.h>
  9. #include <map>
  10. #include <algorithm>
  11. #include <string>
  12. #include <vector>
  13. #include <iostream>
  14. using std::string;
  15. using std::map;
  16. using std::vector;
  17. map<USHORT, SOCKET> socketMap;
  18. //发送数据
  19. void WINAPI SendMsg()
  20. {
  21. while (1)
  22. {
  23. // '+' 43
  24. // '/' 47
  25. // '*' 42
  26. int key = _getch();
  27. if (key == 43) //发送消息
  28. {
  29. printf("【*】群发【/】单发\n");
  30. key = _getch();
  31. printf("发送内容:");
  32. char sendStr[100] = {};
  33. gets_s(sendStr, sizeof(sendStr));
  34. //scanf("%s",sendStr);
  35. int sendRet = 0;
  36. if(key == 42 ) //群发
  37. {
  38. for (auto inter = socketMap.begin(); inter != socketMap.end(); ++inter)
  39. {
  40. SOCKET clientSocket = inter->second;
  41. sendRet = send(clientSocket, sendStr, strlen(sendStr), 0);
  42. }
  43. }
  44. else if(key == 47) //单发
  45. {
  46. printf("客户端端口号:");
  47. int hostPort = 0;
  48. //scanf("%d",&port);
  49. char temp[100] = {};
  50. gets_s((char*)&temp, sizeof(temp));
  51. sscanf(temp, "%d", &hostPort);
  52. if (socketMap.find(hostPort) != socketMap.end())
  53. {
  54. SOCKET clientSocket = socketMap.at(hostPort);
  55. sendRet = send(clientSocket, sendStr, strlen(sendStr), 0);
  56. }
  57. else
  58. {
  59. printf("输入端口号有误\n");
  60. continue;
  61. }
  62. }
  63. if(sendRet != 0)
  64. printf("已发送\n");
  65. else
  66. printf("发送失败\n");
  67. }
  68. }
  69. }
  70. //接收客户端数据
  71. DWORD WINAPI RecvMsg(SOCKET* clientSocket)
  72. {
  73. //int threadId = GetCurrentThreadId();
  74. //int n = 5;
  75. while (1)
  76. {
  77. char recvStr[10000] = {};
  78. int recvRet = recv(*clientSocket, recvStr, sizeof(recvStr), 0);
  79. if (recvRet != -1 && recvRet != 0)
  80. printf("thread【%d】:%s\n=========\n", (int)GetCurrentThreadId(), recvStr);
  81. else
  82. {
  83. auto retVal = std::find_if(socketMap.begin(), socketMap.end(), [clientSocket](map<USHORT, SOCKET>::value_type val)
  84. {
  85. return val.second == *clientSocket;
  86. });
  87. if (retVal != socketMap.end())
  88. {
  89. printf("客户端%d已断开\n", retVal->first);
  90. closesocket(retVal->second);
  91. socketMap.erase(retVal);
  92. break;
  93. }
  94. else
  95. {
  96. printf("没有该客户端\n");
  97. }
  98. }
  99. }
  100. return 0;
  101. }
  102. int main()
  103. {
  104. CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SendMsg, 0, 0, 0);
  105. WSADATA wsaData = { 0 };
  106. WSAStartup(MAKEWORD(2,2),&wsaData);
  107. SOCKET serverSocket = socket(AF_INET,SOCK_STREAM,0);
  108. sockaddr_in sockaddr;
  109. sockaddr.sin_family = AF_INET;
  110. sockaddr.sin_addr.S_un.S_addr = INADDR_ANY; //监听本机任意IP地址的8888端口
  111. //sockaddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
  112. sockaddr.sin_port = htons(8888);
  113. int bindRet = bind(serverSocket, (SOCKADDR*)&sockaddr, sizeof(sockaddr));
  114. if (bindRet == SOCKET_ERROR)
  115. {
  116. printf("绑定失败\n");
  117. closesocket(serverSocket);
  118. WSACleanup();
  119. getchar();
  120. exit(0);
  121. }
  122. int listenRet = listen(serverSocket, 3);
  123. if (listenRet == -1)
  124. {
  125. printf("监听失败\n");
  126. closesocket(serverSocket);
  127. WSACleanup();
  128. system("pause");
  129. return 0;
  130. }
  131. printf("监听中...\n");
  132. while (1)
  133. {
  134. SOCKADDR_IN clientSockAddr_in = {};
  135. int len = sizeof(clientSockAddr_in);
  136. SOCKET clientSocket = accept(serverSocket, (SOCKADDR*)&clientSockAddr_in, &len);
  137. printf("有客户端连接\n");
  138. printf("ip=%s,port=%d\n", inet_ntoa(clientSockAddr_in.sin_addr), ntohs(clientSockAddr_in.sin_port));
  139. socketMap[ntohs(clientSockAddr_in.sin_port)] = clientSocket;
  140. CreateThread(0, 0, (LPTHREAD_START_ROUTINE)RecvMsg, &socketMap[ntohs(clientSockAddr_in.sin_port)], 0, 0);
  141. }
  142. }

客户端

  1. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  2. #define _CRT_SECURE_NO_WARNINGS
  3. #include <WinSock2.h>
  4. #include <WS2tcpip.h>
  5. #pragma comment(lib,"ws2_32.lib")
  6. #include <stdio.h>
  7. #include <iostream>
  8. DWORD WINAPI RecvMsg(const SOCKET* clientSocket)
  9. {
  10. while (1)
  11. {
  12. char recvStr[100] = {};
  13. int recvRet = recv(*clientSocket, recvStr, sizeof(recvStr), 0);
  14. if (recvRet != -1)
  15. printf("服务器说:%s\n", recvStr);
  16. else
  17. {
  18. printf("服务器已断开\n");
  19. closesocket(*clientSocket);
  20. WSACleanup();
  21. system("pause");
  22. closesocket(*clientSocket);
  23. WSACleanup();
  24. exit(0);
  25. }
  26. }
  27. return 0;
  28. }
  29. int main()
  30. {
  31. WSADATA wsaData = { 0 };
  32. WSAStartup(MAKEWORD(2, 2), &wsaData);
  33. SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
  34. //******bind自定义端口号测试*********/
  35. SOCKADDR_IN clientSockAddr_in = { 0 };
  36. clientSockAddr_in.sin_family = AF_INET;
  37. clientSockAddr_in.sin_addr.S_un.S_addr = INADDR_ANY; //本机IP
  38. clientSockAddr_in.sin_port = htons(2222);
  39. if(bind(clientSocket, (SOCKADDR*)&clientSockAddr_in, sizeof(clientSockAddr_in)) == SOCKET_ERROR)
  40. {
  41. std::cout << "绑定套接字失败\n";
  42. closesocket(clientSocket);
  43. WSACleanup();
  44. system("pause");
  45. return 0;
  46. }
  47. /***************************************/
  48. SOCKADDR_IN sockaddr_in;
  49. sockaddr_in.sin_family = AF_INET;
  50. sockaddr_in.sin_addr.S_un.S_addr = inet_addr("172.16.20.203"); //inet_addr("192.168.18.173"); //服务端ip地址
  51. //sockaddr_in.sin_addr.S_un.S_addr = inet_addr("192.168.74.128");
  52. sockaddr_in.sin_port = htons(8888); //服务端监听的端口
  53. int conRet = connect(clientSocket,(SOCKADDR*)&sockaddr_in, sizeof(sockaddr_in));
  54. if (conRet != SOCKET_ERROR)
  55. {
  56. printf("连接成功\n");
  57. CreateThread(0, 0, (LPTHREAD_START_ROUTINE)RecvMsg, &clientSocket, 0, 0);
  58. }
  59. else
  60. {
  61. printf("连接失败,返回%d\n", conRet);
  62. closesocket(clientSocket);
  63. WSACleanup();
  64. }
  65. while (1)
  66. {
  67. printf("输入内容\n");
  68. char sendStr[10000] = {};
  69. //scanf("%s", sendStr); //遇到空格会截断后面内容
  70. gets_s(sendStr, sizeof(sendStr));
  71. int ret = send(clientSocket, sendStr, strlen(sendStr), 0);
  72. if (ret != 0)
  73. printf("客户端发送数据%dbyte\n", ret);
  74. }
  75. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/949687
推荐阅读
相关标签