-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththreaded_server.cpp
113 lines (94 loc) · 2.76 KB
/
threaded_server.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "Socket.hpp"
#include <thread>
#include <vector>
#include <utility>
class Server
{
private:
Socket::conn conns[16] = {}; //connfd of -1 equals unused
std::thread threads[16] = {};
std::unique_ptr<Socket> serverSock;
int getEmptyConnIndex()
{
for (int i = 0; i < sizeof(conns); i++)
{
if(conns[i].connfd == -1)
{
return i;
}
}
return -1;
}
void connRoutine(int index)
{
std::cout << "started new thread with id " << std::this_thread::get_id() << std::endl;
std::string recvString;
while(true)
{
if(conns[index].connRecv(recvString) < 0)
{
//failed to receive msg
std::cout << "lost connection\n";
break;
}
std::cout << "sending message to all conns: " << recvString << std::endl;
sendMsgToAllConns(recvString, index);
}
conns[index].~conn(); //call destructor clearing the socket
memset(&conns[index], -1, sizeof(conns[index])); //empty the element of the array. Ready for next conn
std::cout << "freed conn index " << index << std::endl;
std::cout << "terminating thread with id " << std::this_thread::get_id() << std::endl;
threads[index].detach(); //detach thread from main thread. Gets deleted once out of scope
memset(&threads[index], 0, sizeof(std::thread)); //clear array mem
}
void sendMsgToAllConns(std::string msg, int index)
{
for(int i; i < std::size(conns); i++)
{
if(i != index && conns[i].connfd != -1)
{
conns[i].connSend(msg); //needs error handling
}
}
}
public:
int setupServer(const char* ip, int port)
{
serverSock = std::make_unique<Socket>(ip, port);
if(!serverSock->status)
{
return -1;
}
if(serverSock->setSocketToListen(0) < 0)
{
return -1;
}
return 0;
}
void acceptConnThread()
{
int emptyIndex = getEmptyConnIndex();
if(emptyIndex < 0)
{
std::cout << "cannot accept more connections\n";
return;
}
if(serverSock->acceptConn(conns[emptyIndex]) < 0)
{
std::cout << "error accepting connection\n";
return;
}
std::cout << "accepted new connection with handle " << conns[emptyIndex].connfd << std::endl;
threads[emptyIndex] = std::thread(&Server::connRoutine, this, emptyIndex);
}
};
int main()
{
Server serv;
serv.setupServer("127.0.0.1", 6969);
while (true)
{
serv.acceptConnThread();
}
return 0;
}