GroupB_马喜龙/Public/脸谱-编码规范-B组.docx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Public/脸谱-设计说明书-B组.docx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Public/脸谱-项目计划表-B组.xlsx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Public/脸谱-项目需求分析文档-B组.docx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Public/脸谱-风险控制表-B组.docx | 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Server/马喜龙/code/face_painting_socket_server/ServerSocket.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Server/马喜龙/code/face_painting_socket_server/ServerSocket.h | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Server/马喜龙/code/face_painting_socket_server/ThreadPool.hpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Server/马喜龙/code/face_painting_socket_server/face_painting_socket_server.sln | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
GroupB_马喜龙/Server/马喜龙/code/face_painting_socket_server/main.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
GroupB_ÂíϲÁú/Public/Á³Æ×-±àÂë¹æ·¶-B×é.docxBinary files differ
GroupB_ÂíϲÁú/Public/Á³Æ×-Éè¼ÆËµÃ÷Êé-B×é.docxBinary files differ
GroupB_ÂíϲÁú/Public/Á³Æ×-ÏîÄ¿¼Æ»®±í-B×é.xlsxBinary files differ
GroupB_ÂíϲÁú/Public/Á³Æ×-ÏîÄ¿ÐèÇó·ÖÎöÎĵµ-B×é.docxBinary files differ
GroupB_ÂíϲÁú/Public/Á³Æ×-·çÏÕ¿ØÖƱí-B×é.docxBinary files differ
GroupB_ÂíϲÁú/Server/ÂíϲÁú/code/face_painting_socket_server/ServerSocket.cpp
New file @@ -0,0 +1,187 @@ #include "ServerSocket.h" ServerSocket::ServerSocket() { if (initSocket()) cout << "Socket init successed!" << endl; else cout << "Socket init failed!" << endl; } ServerSocket::~ServerSocket() { closesocket(m_server); WSACleanup(); } bool ServerSocket::initSocket() { WSAData wsa; int val = WSAStartup(MAKEWORD(2, 2), &wsa); if (val != 0) { cout << "WSAStartup failed!"<<endl; } m_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_port = htons(PORT); //å¤ç大å°ç«¯ addr.sin_addr.S_un.S_addr = 0; int ret_bind = bind(m_server, (sockaddr*)&addr, sizeof(addr)); if (ret_bind) { cout << "bind fail:" << WSAGetLastError() << endl; return false; } int ret_listen = listen(m_server, 5); if (ret_listen) { cout << "listen fail:" << WSAGetLastError() << endl; return false; } thread accept_thread(&ServerSocket::acceptThread, this); accept_thread.detach(); // 鲿¢å¼å¸¸ç»æ thread mMap_Delete(&ServerSocket::mMapDelete, this); mMap_Delete.detach(); return true; } void ServerSocket::acceptThread() { while (true) { SOCKET client; SOCKADDR_IN addr; int len = sizeof(addr); cout << "waiting for connect..." << endl; client = accept(m_server, (sockaddr*)&addr, &len); cout << "client:" << client << endl; if (client == SOCKET_ERROR) { cout << "socket å¼å¸¸" << WSAGetLastError() << endl; break; } else if (client == 0) { cout << "socket å·²å ³é:" << WSAGetLastError() << endl; break; } // æ£å¸¸ è¿ä¸äº // å¯å¨é¿è¿æ¥çº¿ç¨ï¼è¿è¡äº¤äº mMapInsert(client); thread heart_check(&ServerSocket::heartBeatThread, this, client); heart_check.detach(); thread recv_send(&ServerSocket::recvAndSendThread, this, client); recv_send.detach(); } } void ServerSocket::recvAndSendThread(SOCKET client) { while (true) { // è§£å³ç²å é®é¢ï¼é¡ºå¸¦ä¹è§£å³äºæå é®é¢ char* buffer = new char[sizeof(Head)]; int len_recv = recv(client, buffer, sizeof(Head), 0); int head_rest = sizeof(Head) - len_recv; // å©ä½é¿åº¦ while (head_rest > 0) { // ä¿è¯æ°æ®å¤´è½å¤å ¨æ¶å° len_recv = recv(client, buffer + (sizeof(Head) - head_rest), head_rest, 0); head_rest -= len_recv; } Head* head = (Head*)buffer; // 转æå¯¹åºç»æä½ï¼åååºå°å æ»é¿åº¦ int len_total = head->len; //int len_total = *(int*)(buffer + 4); // è¿å¯ä»¥ç´æ¥è½¬ä¸ºHead*ï¼æåºé¿åº¦ char* buffer_all = new char[len_total]; memcpy(buffer_all, buffer, sizeof(Head)); // æ·è´æ°æ®å¤´è¿æ»çç¼å²åº int len_rest = len_total - sizeof(Head); while (len_rest > 0) { // ä¿è¯æ°æ®ä½è½å¤å ¨é¨æ¶å° len_recv = recv(client, buffer_all + (len_total - len_rest), len_rest, 0); len_rest -= len_recv; } // æ£å¸¸ //m_clientMap[client] = HEART_CHECK_TIMES; // éç½®å¿è·³éå¼ int type = *(int*)buffer; if (type == 110) { /*TestSturct2* ts2 = (TestSturct2*)buffer_all; // è½¬æ¢æ¶ï¼ä½¿ç¨æ»çbuffer_all if (ts2) { ts2->a = (char*)ts2 + sizeof(TestSturct2); ts2->b = ts2->a + strlen(ts2->a) + 1; cout << ts2->len; cout << "å 容1: " << ts2->a << endl; cout << "å 容2: " << ts2->b << endl; }*/ } /*else if (type == LOGIN_REQ) { // ç»å½è¯·æ± LoginReq* req = (LoginReq*)buffer_all; // è½¬æ¢æ¶ï¼ä½¿ç¨æ»çbuffer_all cout << "ç¨æ·ä¿¡æ¯:" << req->user_name << " " << req->password << endl; Login login; login.business(req, client); // è°ç¨ä¸å¡å¤çAPI }*/ if (type == HEART_CHECK_REQ) { // æ¶å°å¿è·³è¯·æ±å ï¼åååºå HeartCheckRes res; send(client, (char*)&res, res.len, 0); cout << "å·²åå¤å ï¼" << endl; } // åå°ä¸å¨çåå //send(client, buffer_all, len_total, 0); // ç¨å®äºï¼è®°å¾éæ¾å¨æå¼è¾çå å if (buffer) { delete[] buffer; buffer = nullptr; // 鲿¢æéæ¬ç©ºï¼èäº§çæ¬ç©ºæé } if (buffer_all) { delete[] buffer_all; buffer_all = nullptr; } } } void ServerSocket::heartBeatThread(SOCKET client) { while (true) { Sleep(HEARTBEAT_INTERVAL * 1000); mutex heartLock; lock_guard<std::mutex> lock(heartLock); --m_clientMap[client]; } } void ServerSocket::mMapInsert(SOCKET client) { lock_guard<mutex> lg(m_mutex); m_clientMap.insert(make_pair(client, HEART_CHECK_TIMES)); cout << "æå ¥æåï¼times = " << m_clientMap[client] << endl; } void ServerSocket::mMapUpdate(SOCKET client) { lock_guard<mutex> lg(m_mutex); m_clientMap.insert(make_pair(client, HEART_CHECK_TIMES)); } void ServerSocket::mMapDelete() { while (true) { Sleep(HEARTBEAT_INTERVAL * 1000); lock_guard<std::mutex> lock(m_mutex); for (auto& client_socket : m_clientMap) { cout << client_socket.second << endl; if (client_socket.second <= 0) { closesocket(client_socket.first); m_clientMap.erase(client_socket.first); cout << "å é¤è¿æ¥æå" << endl; } } } } GroupB_ÂíϲÁú/Server/ÂíϲÁú/code/face_painting_socket_server/ServerSocket.h
New file @@ -0,0 +1,70 @@ #pragma once #include <WinSock2.h> #include <iostream> #include <map> #include <thread> #include <mutex> #include "ThreadPool.hpp" #pragma comment(lib,"ws2_32.lib") #define PORT 9527 #define HEART_CHECK_REQ 101 #define HEART_CHECK_RES 102 #define HEART_CHECK_TIMES 6 #define HEARTBEAT_INTERVAL 2 using namespace std; struct Head { int type; // åºåä¸ååè½ç±»å int len; // 表示æ´ä¸ªå°å çé¿åº¦ï¼æ¯ä¸ºäºåé¢å¤çç²å é®é¢ç }; // é´éï¼5ç§ï¼éå¼ä¸º6ï¼éåä»6å¼å§ï¼å°0æå°äº0 æå¼/éè¿ // å¿è·³è¯·æ±å struct HeartCheckReq { int type; int len; HeartCheckReq() { type = 101; len = sizeof(HeartCheckReq); } }; // å¿è·³ååºå struct HeartCheckRes { int type; int len; HeartCheckRes() { type = 102; len = sizeof(HeartCheckRes); } }; class ServerSocket { public: ServerSocket(); virtual ~ServerSocket(); bool initSocket(); void acceptThread(); void recvAndSendThread(SOCKET client); void heartBeatThread(SOCKET client); void mMapInsert(SOCKET client); void mMapUpdate(SOCKET client); void mMapDelete(); private: SOCKET m_server; map<SOCKET, int> m_clientMap; mutex m_mutex; }; GroupB_ÂíϲÁú/Server/ÂíϲÁú/code/face_painting_socket_server/ThreadPool.hpp
New file @@ -0,0 +1,147 @@ #pragma once #include <iostream> #include <mutex> #include <atomic> #include <condition_variable> #include <queue> #include <string> using namespace std; template<typename Task, const size_t DEFAULT_THREAD_NUM, const size_t MAX_THREAD_NUM> class ThreadPool { public: ThreadPool() = delete; ThreadPool(const ThreadPool&) = delete; ThreadPool& operator=(const ThreadPool&) = delete; ThreadPool(ThreadPool&&) = delete; ThreadPool& operator=(ThreadPool&&) = delete; explicit ThreadPool(uint32_t timeout) :m_timeout(timeout), m_needRun(true) { for (int i = 0; i < DEFAULT_THREAD_NUM; i++) { thread([this] { RunTask(); }).detach(); } } ~ThreadPool() { m_needRun = false; while (m_runningThreadNum > 0) { m_needRunCondition.notify_all(); } } void Push(Task& task) { PushTask(task); if (m_runningThreadNum < MAX_THREAD_NUM && m_idleThreadNum == 0) { thread([this] { RunTask(); }).detach(); } m_needRunCondition.notify_all(); } private: bool IsQueueEmpty() { lock_guard<mutex> lg(m_mutex); return m_taskQueue.empty(); } bool GetTask(Task& task) { lock_guard<mutex> lg(m_mutex); if (m_taskQueue.empty()) { return false; } task = m_taskQueue.top(); m_taskQueue.pop(); return true; } class NumWrapper { public: NumWrapper() = delete; NumWrapper(atomic<uint32_t>& num) :m_num(num) { m_num++; } ~NumWrapper() { m_num--; } private: atomic<uint32_t>& m_num; }; void Sleep() { mutex needRunMutex; unique_lock<mutex> lock(needRunMutex); NumWrapper idleWraper(m_idleThreadNum); (void)idleWraper; m_needRunCondition.wait_for(lock, std::chrono::seconds(m_timeout), [this] { return !m_needRun || !IsQueueEmpty(); }); } void PushTask(const Task& task) { lock_guard<mutex> lg(m_mutex); m_taskQueue.push(task); } void RunTask() { NumWrapper runWraper(m_runningThreadNum); (void)runWraper; while (m_needRun) { Task task; if (GetTask(task)) { task.Execute(); continue; } Sleep(); if (!m_needRun) { return; } if (GetTask(task)) { task.Execute(); continue; } if (m_runningThreadNum > DEFAULT_THREAD_NUM) { return; } } } private: atomic<uint32_t> m_idleThreadNum; atomic<uint32_t> m_runningThreadNum; atomic_bool m_needRun; mutex m_mutex; condition_variable m_needRunCondition; uint32_t m_timeout; priority_queue<Task> m_taskQueue; }; class Task { public: Task() :m_priority(0) {}; explicit Task(string context) :m_priority(0) { m_context = context; } bool operator<(const Task& t) const { return m_priority < t.m_priority; } void Execute() { lock_guard<mutex> lg(m_mutex); cout << "Task is executed,name is" << m_context << endl; } public: uint32_t m_priority; private: string m_context; static mutex m_mutex; }; GroupB_ÂíϲÁú/Server/ÂíϲÁú/code/face_painting_socket_server/face_painting_socket_server.sln
New file @@ -0,0 +1,28 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.12.35521.163 d17.12 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "face_painting_socket_server", "face_painting_socket_server.vcxproj", "{8F47EF20-7DBA-475C-ABA7-C468E46049F2}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Debug|x64.ActiveCfg = Debug|x64 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Debug|x64.Build.0 = Debug|x64 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Debug|x86.ActiveCfg = Debug|Win32 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Debug|x86.Build.0 = Debug|Win32 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Release|x64.ActiveCfg = Release|x64 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Release|x64.Build.0 = Release|x64 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Release|x86.ActiveCfg = Release|Win32 {8F47EF20-7DBA-475C-ABA7-C468E46049F2}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal GroupB_ÂíϲÁú/Server/ÂíϲÁú/code/face_painting_socket_server/main.cpp
New file @@ -0,0 +1,39 @@ #include <iostream> #include "ServerSocket.h" #include "ThreadPool.hpp" using namespace std; #define DEFAULT_THREAD_NUM 3 #define MAX_THREAD_NUM 6 #define TIME_OUT 500 mutex Task::m_mutex; int main() { ServerSocket server1; string cmd; while (cin>>cmd) { if (cmd == "quit") { break; } } /*ThreadPool<Task, DEFAULT_THREAD_NUM, MAX_THREAD_NUM> threadPool_(TIME_OUT); Task task1("name_1"); Task task2("name_2"); Task task3("name_3"); Task task4("name_4"); task4.m_priority = 4; task3.m_priority = 8; task2.m_priority = 2; task1.m_priority = 5; threadPool_.Push(task1); threadPool_.Push(task2); threadPool_.Push(task3); threadPool_.Push(task4);*/ system("pause"); return 0; }