Xinqi Bao's Git

first commit, implemented game wordscapes
[CheaterHub.git] / server / cheaterHub.cc
1 #include <netinet/in.h>
2 #include <sys/socket.h>
3 #include <unistd.h>
4
5 #include <boost/algorithm/string/classification.hpp>
6 #include <boost/algorithm/string/split.hpp>
7 #include <condition_variable>
8 #include <cstdio>
9 #include <iostream>
10 #include <mutex>
11 #include <queue>
12 #include <string>
13 #include <thread>
14
15 #include "wordscapes/wordscapes.h"
16
17 #define PORT 2020
18
19 std::queue<std::pair<int, std::string>> qu;
20
21 std::mutex mtx_th;
22 std::mutex mtx_qu;
23
24 Wordscapes ws;
25
26 void thread_on_msg(int i)
27 {
28 while (true)
29 {
30 mtx_th.lock();
31
32 mtx_qu.lock();
33 if (qu.empty())
34 {
35 mtx_qu.unlock();
36 continue;
37 }
38 int client_fd = qu.front().first;
39 std::string msg = qu.front().second;
40 qu.pop();
41 mtx_qu.unlock();
42
43 // do msg
44 std::cout << "Thread " << i << " receive: " << msg << std::endl;
45
46 std::vector<std::string> msg_vt;
47 boost::split(msg_vt, msg, boost::is_any_of(";"));
48
49 auto result = ws.solve(msg_vt[0], msg_vt[1]);
50
51 std::string ret = "";
52 for (auto& res : result) ret += res + ';';
53
54 send(client_fd, ret.c_str(), ret.size(), 0);
55 std::cout << "Thread " << i << " send: " << ret << std::endl;
56
57 close(client_fd);
58
59 mtx_qu.lock();
60 if (!qu.empty()) mtx_th.unlock();
61 mtx_qu.unlock();
62 }
63 }
64
65 int main()
66 {
67 struct sockaddr_in server_addr;
68 struct sockaddr_storage client_addr;
69 int addrlen = sizeof(server_addr);
70 server_addr.sin_family = AF_INET;
71 server_addr.sin_addr.s_addr = INADDR_ANY;
72 server_addr.sin_port = htons(PORT);
73
74 int server_fd;
75
76 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0)
77 {
78 perror("socket failed");
79 exit(EXIT_FAILURE);
80 }
81
82 int opt = 1;
83 if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt,
84 sizeof(opt)))
85 {
86 perror("setsockopt");
87 exit(EXIT_FAILURE);
88 }
89
90 if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) <
91 0)
92 {
93 perror("bind failed");
94 exit(EXIT_FAILURE);
95 }
96
97 if (listen(server_fd, 5) < 0)
98 {
99 perror("listen");
100 exit(EXIT_FAILURE);
101 }
102
103 std::thread threads[5];
104 for (int i = 0; i < 5; i++) threads[i] = std::thread(thread_on_msg, i);
105
106 while (true)
107 {
108 socklen_t clientAddr_len = sizeof(client_addr);
109 int new_socket =
110 accept(server_fd, (struct sockaddr*)&client_addr, &clientAddr_len);
111 char buffer[1024] = {0};
112 recv(new_socket, buffer, 1024, 0);
113
114 mtx_qu.lock();
115 qu.push({new_socket, std::string(buffer)});
116 mtx_qu.unlock();
117 mtx_th.unlock();
118 }
119 for (int i = 0; i < 5; i++) threads[i].join();
120
121 return 0;
122 }