-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.cpp
More file actions
115 lines (102 loc) · 3.8 KB
/
server.cpp
File metadata and controls
115 lines (102 loc) · 3.8 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
114
115
#include <fstream>
#include <signal.h>
#include <net.h>
class PacketSender{
std::ifstream file;
void WriteFromFile(Socket& socket, SocketEventHandler::Event event){
char buffer[0x400];
file.read(buffer, sizeof(buffer));
int read = file.gcount(), sent;
socket.Send(buffer, read, sent);
if (sent < read)
if(file.seekg(sent - read, std::ios::cur).fail()){
file.clear();
file.seekg(0, std::ios::beg);
}
if (file.eof()){
socket.UnregisterHandler(SocketEventHandler::NormalWrite);
file.close();
if (finishedCallback)
finishedCallback(this);
}
}
public:
std::function<void(PacketSender*)> finishedCallback;
PacketSender(Socket& socket, const char* fileName) : file(fileName, std::ios::binary | std::ios::in) {
if (file.is_open())
socket.RegisterHandler(SocketEventHandler::NormalWrite, [this] (Socket& socket, SocketEventHandler::Event event) { this->WriteFromFile(socket, event); });
else
if (finishedCallback)
finishedCallback(this);
}
};
void DeleteSocket(Socket& socket, SocketEventHandler::Event event){
delete &socket;
std::cout << "Closing connection!\n";
}
void ReadInComingMessage(Socket& caller, SocketEventHandler::Event event){
std::string message;
message.resize(0x400);
int bytes = 0;
if(!caller.Recv(message.data(), message.size(), bytes)) {
logger << "Failed to recv connection " << FormatError(NET_GET_ERROR) << '\n';
return;
}
if(bytes == 0) {
logger << "Receive OEF, closing connection\n";
delete &caller;
return;
}
message.resize(bytes);
std::cout << "Socket[" << std::hex << caller.GetHandle() << std::dec << "] sent " << bytes << " bytes: " << message << '\n';
}
void CloseAndExit(Socket& caller, SocketEventHandler::Event event);
void OnNewConnection(Socket& listener, SocketEventHandler::Event event){
Socket* newCaller = new Socket;
if(!listener.Accept(*newCaller)){
logger << "Failed to accept connection\n"<< FormatError(NET_GET_ERROR);
return;
}
newCaller->SetBlocking(false);
std::cout << "Accepted a connection...\n";
newCaller->RegisterHandler(SocketEventHandler::NormalRead, ReadInComingMessage);
newCaller->RegisterHandler(SocketEventHandler::SocketError, CloseAndExit);
newCaller->RegisterHandler(SocketEventHandler::Disconnected, DeleteSocket);
}
std::condition_variable cvWakeUp;
volatile sig_atomic_t signalStatus = 0;
void CloseAndExit(Socket& caller, SocketEventHandler::Event event) {
logger << "An error has occurred.\n";
caller.Close();
signalStatus = -1;
cvWakeUp.notify_all();
}
void HandleInterupt(int sig){
signalStatus = sig;
std::cout << "Ctrl + C detected\n";
cvWakeUp.notify_all();
}
int main() {
signal(SIGINT, HandleInterupt);
std::mutex trapMutex;
logger.out(std::cerr);
Networking net;
Socket lSocket;
lSocket.SetBlocking(false);
if (!lSocket.Create(4)) {
logger << "Can't create socket\n" << FormatError(NET_GET_ERROR);
return EXIT_FAILURE;
}
auto address = IPv4Address(AddressType::Remote, short(8080));
if (!lSocket.Listen(address, 0xFF)) {
logger << "Can't bind the socket\n" << FormatError(NET_GET_ERROR);
return EXIT_FAILURE;
}
std::cout << "Listening...\n";
lSocket.RegisterHandler(SocketEventHandler::Event::NormalRead, OnNewConnection);
std::unique_lock<std::mutex> lk(trapMutex);
cvWakeUp.wait(lk, []{
return signalStatus != 0;
});
std::cout << "Closing the server!\n";
}