-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServerClass.cpp
More file actions
164 lines (140 loc) · 4.23 KB
/
ServerClass.cpp
File metadata and controls
164 lines (140 loc) · 4.23 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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include "ServerClass.h"
void ServerClass::sendData(SOCKET senderSock, const std::string& msg)
{
std::lock_guard<std::mutex> lock(clientsMutex);
for (SOCKET client : clients) {
if (client != senderSock) {
send(client, msg.c_str(), msg.size(), 0);
}
}
}
void ServerClass::recieveData(SOCKET clientSock, const std::string& username)
{
std::vector<char> buffer(1024);
while (running) {
int bytesReceived = recv(clientSock, buffer.data(), buffer.size(), 0);
if (bytesReceived > 0) {
std::string msg(buffer.begin(), buffer.begin() + bytesReceived);
if (msg == "EndConnTrue!")
{
std::string discmesg = "\n[" + username + "] disconnected\n";
send(clientSock, discmesg.c_str(), discmesg.size(), 0);
std::cout << "\n[" << username << "] requested disconnect.\n";
{
std::lock_guard<std::mutex> lock(clientsMutex);
clients.erase(std::remove(clients.begin(), clients.end(), clientSock), clients.end());
}
closesocket(clientSock);
break;
}
else if (msg == "!Help")
{
std::string helpMsg = "\n1./quit, disconnects you.\n2./help opens help.\n";
send(clientSock, helpMsg.c_str(), helpMsg.size(), 0);
}
std::string finalmsg = "[" + username + "] > " + msg + "\n";
std::cout << finalmsg;
sendData(clientSock, finalmsg);
}
else {
std::cout << "\nClient [" << username << "] disconnected or error.\n";
{
std::lock_guard<std::mutex> lock(clientsMutex);
clients.erase(std::remove(clients.begin(), clients.end(), clientSock), clients.end());
}
closesocket(clientSock);
break;
}
}
}
int ServerClass::StartServer()
{
running = true;
std::string ipaddres = "127.0.0.1";
std::string portBuff = "";
std::cout << "please specify your ip addres: ";
std::getline(std::cin, ipaddres);
std::cout << "\nplease specify your port: ";
std::getline(std::cin, portBuff);
port = static_cast<WORD>(std::stoi(portBuff));
erStat = WSAStartup(MAKEWORD(2, 2), &WsaData);
if (erStat != 0) {
std::cout << "Error WinSock version initializaion #";
std::cout << WSAGetLastError();
return 1;
}
else
std::cout << "WinSock initialization is DONE!\n";
ServSocket = socket(AF_INET, SOCK_STREAM, 0);
if (ServSocket == INVALID_SOCKET)
{
std::cout << "Error when initializing server socket. Closing";
closesocket(ServSocket);
WSACleanup();
return 1;
}
else
std::cout << "Initializing server socket is DONE!\n";
in_addr ip_to_num {};
erStat = inet_pton(AF_INET, ipaddres.c_str(), &ip_to_num);
if (erStat <= 0)
{
std::cout << "Error in IP translation to numeric format";
closesocket(ServSocket);
WSACleanup();
return 1;
}
else
std::cout << "Succesfully transfered IP to byte format!\n";
sockaddr_in servInfo;
ZeroMemory(&servInfo, sizeof(servInfo));
servInfo.sin_family = AF_INET;
servInfo.sin_port = htons(port);
servInfo.sin_addr = ip_to_num;
erStat = bind(ServSocket, (sockaddr*)&servInfo, sizeof(servInfo));
if (erStat != 0)
{
std::cout << "Error socket binding to server info. Error #";
std::cout << WSAGetLastError();
closesocket(ServSocket);
WSACleanup();
return 1;
}
else
std::cout << "Binding socket to Server info done!\n";
erStat = listen(ServSocket, SOMAXCONN);
if (erStat != 0)
{
std::cout << "Can`t start to listen to. Error #";
std::cout << WSAGetLastError();
closesocket(ServSocket);
WSACleanup();
return 1;
}
else
std::cout << "listening...\n";
while (true) {
sockaddr_in clientInfo{};
int clientInfoSize = sizeof(clientInfo);
SOCKET clientSock = accept(ServSocket, (sockaddr*)&clientInfo, &clientInfoSize);
if (clientSock == INVALID_SOCKET) {
std::cout << "Client accept failed\n";
continue;
}
char clientIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &clientInfo.sin_addr, clientIP, INET_ADDRSTRLEN);
std::cout << "Client connected: " << clientIP << "\n";
// Receive username
std::vector<char> ClientUser(32);
int bytes = recv(clientSock, ClientUser.data(), ClientUser.size() - 1, 0);
std::string username = (bytes > 0) ? std::string(ClientUser.data(), bytes) : "UNDENTIFIED";
{
std::lock_guard<std::mutex> lock(clientsMutex);
clients.push_back(clientSock);
}
std::thread(&ServerClass::recieveData, this, clientSock, username).detach();
}
closesocket(ServSocket);
WSACleanup();
return 0;
}