19 std::cout <<
"ServerSocket constructor" << std::endl;
23 if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
24 std::cout <<
"WSAStartup failed: " << WSAGetLastError() << std::endl;
25 throw std::runtime_error(
"Failed to initialize Winsock");
27 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
28 if (sockfd == INVALID_SOCKET) {
29 std::cout <<
"Error at socket(): " << WSAGetLastError() << std::endl;
31 throw std::runtime_error(
"Failed to create socket");
33 #elif defined(__unix__
) || defined(__unix__
) || defined(__APPLE__) || defined(__MACH__)
34 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
35 std::cout <<
"coucou " << std::endl;
37 std::cout <<
"Error sockfd < 0 sockfd : " << sockfd << std::endl;
38 throw std::runtime_error(
"Failed to create socket");
41 timeout = std::make_unique<
struct timeval>();
44 std::cout <<
"Socket created successfully (fd: " << sockfd <<
")" << std::endl;
54 #elif defined(__unix__
) || defined(__unix__
) || defined(__APPLE__) || defined(__MACH__)
65 memset(&serv_addr, 0,
sizeof(serv_addr));
66 serv_addr.sin_family = AF_INET;
67 serv_addr.sin_port = htons(port);
68 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
69 if (bind(sockfd, (
struct sockaddr *)&serv_addr,
sizeof(serv_addr)) < 0) {
70 throw std::runtime_error(
"Failed to bind socket");
91 char *buffer =
static_cast<
char *>(malloc(
sizeof(SplitPacket)));
92 memset(buffer, 0,
sizeof(SplitPacket));
93 memcpy(buffer, packet,
sizeof(SplitPacket));
94 if (sendto(sockfd,
reinterpret_cast<
const char *>(buffer),
sizeof(SplitPacket), 0, (
struct sockaddr *)&dest,
96 throw std::runtime_error(
"Failed to send packet");
108 for (
auto &[i, cli, splitPackets, lastReceived] : clients) {
115 clients.emplace_back(id, client, std::vector<std::tuple<std::shared_ptr<SplitPacket>, timeval>>(), timeval());
125 if (clients.empty()) {
128 for (
auto &[id, cli, splitPackets, lastReceived] : clients) {
129 if (cli.sin_addr.s_addr == client.sin_addr.s_addr && cli.sin_port == client.sin_port) {
143 return manageClientsBuffer();
235 FD_SET(sockfd, &_readfds);
246 if (lastMessage ==
"ping") {
247 std::unique_ptr<Packet> packet = std::make_unique<Packet>();
248 packet->code = MESSAGE;
249 packet->data_size = 4;
250 packet->data = malloc(4);
251 memcpy(packet->data,
"pong", 4);
252 send(packet.get(), lastClientAddress);
254 if (lastMessage ==
"exit")
275 struct sockaddr_in
ServerSocket::getClientAddress(
int id)
277 for (
auto &[i, cli, splitPackets, lastReceived] : clients) {
282 throw std::runtime_error(
"Client not found");
291 for (
auto &[id, cli, splitPackets, lastReceived] : clients) {
303 std::unique_ptr<SplitPacket> splitPacket = std::make_unique<SplitPacket>();
304 splitPacket->code = packet->code;
308 splitPacket->data[0] =
'\0';
309 splitPacket->packet_id = 0;
310 splitPacket->max_packet_id = 0;
311 memset(splitPacket->data, 0, 1024);
312 memcpy(splitPacket->data, packet->data, packet->data_size);
313 sendPacket(splitPacket.get(), dest);
315 splitPacket->max_packet_id = packet->data_size / 1024 + 1;
317 splitPacket->packet_id = i;
318 memset(splitPacket->data, 0, 1024);
319 memcpy(splitPacket->data, (
char *)packet->data + i * 1024, 1024);
320 sendPacket(splitPacket.get(), dest);
324 splitPacket->packet_id = i + 1;
325 memset(splitPacket->data, 0, 1024);
326 memcpy(splitPacket->data, (
char *)packet->data + i * 1024 + 1, rest);
327 sendPacket(splitPacket.get(), dest);
337 struct sockaddr_in cli_addr {
340 std::shared_ptr<SplitPacket> packet = std::make_shared<SplitPacket>();
342 socklen_t len =
sizeof(cli_addr);
343 char *buffer =
static_cast<
char *>(malloc(
sizeof(SplitPacket)));
344 memset(buffer, 0,
sizeof(SplitPacket));
345 if (select(sockfd + 1, &_readfds,
nullptr,
nullptr, timeout.get()) < 0) {
347 throw std::runtime_error(
"Failed to read from socket");
348 }
else if (FD_ISSET(sockfd, &_readfds)) {
349 if (recvfrom(sockfd, buffer,
sizeof(SplitPacket), 0, (
struct sockaddr *)&cli_addr, &len) < 0) {
350 throw std::runtime_error(
"Failed to read from socket");
357 memcpy(packet.get(), buffer,
sizeof(SplitPacket));
365 for (
auto &[i, cli, splitPackets, lastReceived] : clients) {
367 gettimeofday(&recvTime,
nullptr);
368 gettimeofday(&lastReceived,
nullptr);
369 splitPackets.emplace_back(packet, recvTime);
381 std::unique_ptr<Packet> packet = std::make_unique<Packet>();
383 long long int size = 0;
384 std::unique_ptr<
struct timeval> now = std::make_unique<
struct timeval>();
385 std::unique_ptr<
struct timeval> diff = std::make_unique<
struct timeval>();
387 for (
auto &[id, cli, splitPackets, lastReceived] : getClients()) {
388 auto it = splitPackets.begin();
389 while (it != splitPackets.end()) {
390 auto &[splitPacket, recvTime] = *it;
391 if (splitPacket->packet_id == 0 && splitPacket->max_packet_id == 0) {
392 packet->code = splitPacket->code;
393 packet->data_size = splitPacket->max_packet_id * 1024;
394 if (packet->data_size == 0) {
395 packet->data_size = 1024;
397 packet->data = malloc(packet->data_size);
398 memcpy(packet->data, splitPacket->data, packet->data_size);
399 it = splitPackets.erase(it);
400 return std::make_tuple(std::move(packet), id);
402 if (splitPacket->packet_id == counter) {
404 size += strlen(splitPacket->data);
405 if (splitPacket->packet_id == splitPacket->max_packet_id) {
406 packet->code = splitPacket->code;
407 packet->data_size = size;
408 packet->data = malloc(packet->data_size + 1);
409 memset(packet->data, 0, packet->data_size + 1);
410 int counterAssign = 0;
411 auto itAssign = splitPackets.begin();
412 while (itAssign != splitPackets.end()) {
413 auto &[splitPacketAssign, recvTimeAssign] = *itAssign;
414 memcpy((
char *)packet->data + counterAssign * 1024, splitPacketAssign->data,
415 strlen(splitPacketAssign->data));
417 itAssign = splitPackets.erase(itAssign);
419 return std::make_tuple(std::move(packet), id);
431 for (
auto &[idtimeout, clitimeout, splitPacketstimeout, lastReceivedtimeout] : getClients()) {
432 auto ittimeout = splitPacketstimeout.begin();
433 while (ittimeout != splitPacketstimeout.end()) {
434 auto &[splitPackettimeout, recvTimetimeout] = *ittimeout;
435 gettimeofday(now.get(),
nullptr);
436 timersub(now.get(), &recvTimetimeout, diff.get());
437 if (diff->tv_sec > 1) {
438 ittimeout = splitPacketstimeout.erase(ittimeout);
444 return std::make_tuple(
nullptr, 0);
457 gettimeofday(&now,
nullptr);
458 for (
auto &[id, cli, splitPackets, lastReceived] : getClients()) {
459 timersub(&now, &lastReceived, &diff);
460 if (diff.tv_sec > 1) {
461 std::shared_ptr<Packet> packet = std::make_shared<Packet>();
462 packet->code = EVENT;
463 packet->data_size = strlen(
"player left");
464 packet->data = malloc(packet->data_size);
465 memcpy(packet->data,
"player left", packet->data_size);
466 broadcast(packet.get());
467 auto it = getClients().begin();
468 while (it != getClients().end()) {
469 auto &[iddel, clidel, splitPacketsdel, lastReceiveddel] = *it;
472 it = getClients().erase(it);
489 newClientConnected =
true;
499 if (!newClientConnected) {
502 newClientConnected =
false;
511 std::cout <<
"Clients dump:" << std::endl;
512 for (
auto &[id, cli, splitPackets, lastReceived] : getClients()) {
513 std::cout <<
"id: " << id;
514 std::cout <<
" cli.sin_family: " << cli.sin_family;
515 std::cout <<
" cli.sin_port: " << cli.sin_port;
516 std::cout <<
" cli.sin_addr.s_addr: " << cli.sin_addr.s_addr;
517 std::cout <<
" splitPackets.size(): " << splitPackets.size();
518 std::cout <<
" lastReceived.tv_sec: " << lastReceived.tv_sec;
519 std::cout <<
" lastReceived.tv_usec: " << lastReceived.tv_usec << std::endl;