server.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include "server.h"
  2. void *get_client_addr(struct sockaddr *sa) {
  3. if (sa->sa_family == AF_INET) {
  4. return &(((struct sockaddr_in *) sa)->sin_addr);
  5. }
  6. return &(((struct sockaddr_in6 *) sa)->sin6_addr);
  7. }
  8. int Server::exec() {
  9. if (!createSocket()) {
  10. return -1;
  11. }
  12. std::cout << "Server: server created and listening on port " << port << std::endl;
  13. while (true) {
  14. std::cout << "Server: awaiting connection...\n";
  15. ClientData *data = new ClientData(); // would be deleted in thread after its finishing
  16. data->sockd = accept(sock, (struct sockaddr *) &data->client_sockaddr, &data->client_sockaddr_size);
  17. std::cout << "Server: got new connection, creating worker thread." << std::endl;
  18. clients_threads.emplace_back(std::thread(&Server::handleRequest, this, data));
  19. std::cout << "Server: created worker thread " << clients_threads.back().get_id();
  20. }
  21. }
  22. bool Server::createSocket() {
  23. std::cout << "Server: creating socket..." << std::endl;
  24. sock = socket(AF_INET, SOCK_STREAM, 0);
  25. int on = 1;
  26. setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &on, sizeof(on));
  27. /* initialize the server's sockaddr */
  28. struct sockaddr_in server_sockaddr;
  29. memset(&server_sockaddr, 0, sizeof(server_sockaddr));
  30. server_sockaddr.sin_family = AF_INET;
  31. server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  32. server_sockaddr.sin_port = htons(port);
  33. printf("Server: Binding socket %d to sockaddr %p with size %d\n", sock, (struct sockaddr *) &server_sockaddr, sizeof(server_sockaddr));
  34. int bind_result = bind(sock, (struct sockaddr *) &server_sockaddr, sizeof(server_sockaddr));
  35. if (bind_result < 0) {
  36. std::cout << "Server: Error: socket bind failed!" << std::endl;
  37. return false;
  38. }
  39. listen(sock, max_connections);
  40. if (sock < 0) {
  41. std::cout << "Server: Error, cannot create socket" << std::endl;
  42. return false;
  43. }
  44. return true;
  45. }
  46. void Server::handleRequest(ClientData* client_data) {
  47. char ip[17];
  48. inet_ntop(AF_INET, get_client_addr((struct sockaddr *)&client_data->client_sockaddr), ip, sizeof(ip));
  49. printf("Worker %u: Established connection with %s beginning work.\n", std::this_thread::get_id(), ip);
  50. const int request_buffer_size = 65536;
  51. char request[request_buffer_size];
  52. // Receiving client type: reader or writer
  53. int bytes_recvd = recv(client_data->sockd, request, request_buffer_size - 1, 0);
  54. if (bytes_recvd < 0) {
  55. fprintf(stderr, "Worker %u: error recv: %s\n", std::this_thread::get_id(), strerror(errno));
  56. delete client_data;
  57. return;
  58. }
  59. request[bytes_recvd] = '\0';
  60. if (strcmp(request, "reader") == 0) {
  61. printf("Worker %u: Client %s is READER.\n", std::this_thread::get_id(), ip);
  62. client_readers_lock.lock();
  63. clients_readers.push_back(*client_data);
  64. client_readers_lock.unlock();
  65. } else if (strcmp(request, "writer") == 0) {
  66. printf("Worker %u: Client %s is WRITER.\n", std::this_thread::get_id(), ip);
  67. while (true) {
  68. int bytes_recvd = recv(client_data->sockd, request, request_buffer_size - 1, 0);
  69. if (bytes_recvd <= 0) {
  70. fprintf(stderr, "Worker %u: error recv: %s\n", std::this_thread::get_id(), strerror(errno));
  71. delete client_data;
  72. return;
  73. }
  74. request[bytes_recvd] = '\0';
  75. printf("Worker %u: received message: %s\n", std::this_thread::get_id(), request);
  76. client_readers_lock.lock();
  77. for (int i = 0; i < clients_readers.size(); ++i) {
  78. send(clients_readers[i].sockd, request, bytes_recvd, 0);
  79. }
  80. client_readers_lock.unlock();
  81. }
  82. } else {
  83. printf("Worker %u: Client %s is UNRECOGNIZED. Error!\n", std::this_thread::get_id(), ip);
  84. }
  85. }