-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
113 lines (94 loc) · 3.62 KB
/
main.cpp
File metadata and controls
113 lines (94 loc) · 3.62 KB
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 "server_session_controller.h"
#include <iostream>
#include <string>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <thread>
#include <regex>
#include <sys/epoll.h>
bool isNumeric(const std::string& string) {
static const std::regex numberRegex(
R"(^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?$)"
);
return std::regex_match(string, numberRegex);
}
std::string requestString(const std::string& message) {
std::string userInput;
std::wcout << message.c_str();
std::getline(std::cin, userInput);
return userInput;
}
int requestInt(const std::string& message) {
std::string userInput;
while (true) {
std::wcout << message.c_str();
std::getline(std::cin, userInput);
if (isNumeric(userInput)) {
return std::stoi(userInput);
}
std::wcout << "Invalid input! Try again\n";
}
}
void clientManager(int serverSocket, int clientSocket) {
auto serverSessionController = std::make_shared<ServerSessionController>(serverSocket, clientSocket);
std::thread networkingSession([serverSessionController]() {
serverSessionController->networkingSession();
});
while (serverSessionController->isConnected()) {
if (serverSessionController->hasRequest()) {
ServerSessionController::Packet packet = serverSessionController->popRequest();
std::wcout << "Received packet id: " << packet.id << std::endl;
serverSessionController->pushResponse(packet);
}
}
std::wcout << "Terminated!" << std::endl;
networkingSession.detach();
}
int main() {
std::string interface = requestString("Interface (string): ");
int port = requestInt("Server port (int): ");
ServerSessionController tempServerSessionController;
std::string containerIP = tempServerSessionController.getLocalIpAddress(interface);
sockaddr_in serverAddress;
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = htons(port);
serverAddress.sin_addr.s_addr = inet_addr(containerIP.c_str());
int serverSocket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
if(bind(serverSocket, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) {
std::wcout << "Bind failed!" << std::endl;
return -1;
}
// Create epoll
int epollFd = epoll_create1(0);
if (epollFd == -1) {
std::wcout << "Failed to create epoll!" << std::endl;
}
// Set epoll action for server
struct epoll_event serverEvents;
serverEvents.events = EPOLLIN | EPOLLOUT;
serverEvents.data.fd = serverSocket;
if (epoll_ctl(epollFd, EPOLL_CTL_ADD, serverSocket, &serverEvents) == -1) {
std::wcout << "Failed to set epoll_ctl!" << std::endl;
return 1;
}
listen(serverSocket, 5);
std::vector<std::thread> clientConnections;
while (true) {
const int MAX_EVENTS = 10;
struct epoll_event events[MAX_EVENTS];
int epollRequestCount = epoll_wait(epollFd, events, MAX_EVENTS, -1);
for (int index = 0; index < epollRequestCount; ++index) {
if (events[index].data.fd == serverSocket) {
int clientSocket = accept4(serverSocket, nullptr, nullptr, SOCK_NONBLOCK);
std::wcout << "New clientSocket: " << clientSocket << std::endl;
clientConnections.push_back(std::thread(
clientManager,
serverSocket,
clientSocket
));
}
}
}
return 0;
}