codegod313

Chpoks_SERVER

Mar 10th, 2023 (edited)
510
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 22.06 KB | None | 0 0
  1. #include <iostream>
  2. #include <unistd.h>
  3. #include <sys/socket.h>
  4. #include <memory.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <string>
  8. #include <poll.h>
  9. #include <vector>
  10. #include <chrono>
  11. #include <ctime>
  12. #include <fstream>
  13. #include <limits>
  14. #include <pthread.h>
  15.  
  16. #define SERVER_ADDRESS "192.168.1.83"
  17. #define SERVER_PORT 20200
  18. #define BUFFER_SIZE 1024
  19.  
  20. #define NUMBER_OF_CONNECTIONS 15
  21.  
  22. #define WRONG_COMMAND_MESSAGE "Wrong command !!!!!!!!\n"
  23. #define NO_SUCH_FILE_MESSAGE "Can not find file"
  24. #define FILE_FOUND_MESSAGE "OK"
  25. #define QUIT_MESSAGE "disconnect"
  26.  
  27. #define ECHO_COMMAND "echo"
  28. #define TIME_COMMAND "time"
  29. #define DOWNLOAD_COMMAND "download"
  30.  
  31. #define SOCKET_TYPE SOCK_DGRAM
  32.  
  33. #define NUM_OF_THREADS_IN_POOL 10
  34.  
  35. struct buffers
  36. {
  37.     std::string inbuf;
  38.     char *outBuf;
  39.     size_t outBufPos;
  40.     size_t outBufLength;
  41. };
  42.  
  43. int sd;
  44. std::vector<struct pollfd> fds;
  45. std::vector<struct sockaddr_in> clientAddresses;
  46. std::vector<struct buffers> sBuffers;
  47. std::vector<pthread_t> threads(10);
  48. int lastThread = 0;
  49.  
  50. bool pollhup = false;
  51.  
  52. void configureServer()
  53. {
  54.     sd = socket(AF_INET, SOCKET_TYPE, 0);
  55.     struct sockaddr_in address;
  56.     memset(&address, 0, sizeof(sockaddr));
  57.     address.sin_family = AF_INET;
  58.     address.sin_port = htons(SERVER_PORT);
  59.     address.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);
  60.  
  61.     int rc = bind(sd, (struct sockaddr *)&address, sizeof(address));
  62.     if (rc < 0)
  63.     {
  64.         std::cout << "Bind failed" << std::endl;
  65.     }
  66.     struct pollfd serverFd;
  67.     serverFd.fd = sd;
  68.     serverFd.events = POLLIN;
  69.     fds.push_back(serverFd);
  70.     listen(sd, NUMBER_OF_CONNECTIONS);
  71. }
  72. void processData(std::string data, int numberOfSocket)
  73. {
  74.     bool isSatisfied = false;
  75.     data.erase(data.begin() + data.size() - 1, data.begin() + data.size());
  76.     int spacePos = data.find_first_of(" ");
  77.     std::string command, parameter;
  78.     if (spacePos == std::string::npos)
  79.     {
  80.         command = data;
  81.         parameter = "";
  82.     }
  83.     else
  84.     {
  85.         command = data.substr(0, spacePos);
  86.         parameter = data.substr(spacePos + 1, data.size() - spacePos - 1);
  87.     }
  88.     if (command == ECHO_COMMAND)
  89.     {
  90.         if (parameter != "")
  91.         {
  92.             send(fds[numberOfSocket].fd, parameter.data(), parameter.size(), 0);
  93.         }
  94.         else
  95.         {
  96.             std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  97.             send(fds[numberOfSocket].fd, wrongCommandString.data(), wrongCommandString.size(), 0);
  98.         }
  99.         isSatisfied = true;
  100.     }
  101.     if (command == TIME_COMMAND)
  102.     {
  103.         if (parameter == "")
  104.         {
  105.             auto timeC = std::chrono::system_clock::now();
  106.  
  107.             std::time_t time_conv = std::chrono::system_clock::to_time_t(timeC);
  108.             std::string timeStr(std::ctime(&time_conv));
  109.             timeStr.erase(timeStr.begin() + timeStr.size() - 1, timeStr.begin() + timeStr.size());
  110.             send(fds[numberOfSocket].fd, timeStr.data(), timeStr.size(), 0);
  111.         }
  112.         else
  113.         {
  114.             std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  115.             send(fds[numberOfSocket].fd, wrongCommandString.data(), wrongCommandString.size(), 0);
  116.         }
  117.         isSatisfied = true;
  118.     }
  119.     if (command == DOWNLOAD_COMMAND)
  120.     {
  121.         std::ifstream fin;
  122.         fin.open(parameter, std::ios::binary | std::ios::in);
  123.         if (!fin.is_open())
  124.         {
  125.             std::string noFileMessage = NO_SUCH_FILE_MESSAGE;
  126.             send(fds[numberOfSocket].fd, noFileMessage.data(), noFileMessage.size(), 0);
  127.         }
  128.         else
  129.         {
  130.             std::string fileFoundMessage = FILE_FOUND_MESSAGE;
  131.             send(fds[numberOfSocket].fd, fileFoundMessage.data(), fileFoundMessage.size(), 0);
  132.             fin.ignore(std::numeric_limits<std::streamsize>::max());
  133.             std::streamsize length = fin.gcount();
  134.             fin.clear();
  135.             fin.seekg(0, std::ios_base::beg);
  136.             size_t lengthFile = length;
  137.             char *fileData = (char *)malloc(sizeof(char) * lengthFile);
  138.             fin.read(fileData, lengthFile);
  139.             sBuffers[numberOfSocket - 1].outBuf = fileData;
  140.             sBuffers[numberOfSocket - 1].outBufPos = 0;
  141.             sBuffers[numberOfSocket - 1].outBufLength = lengthFile;
  142.             send(fds[numberOfSocket].fd, &lengthFile, sizeof(size_t), 0);
  143.         }
  144.         fin.close();
  145.         isSatisfied = true;
  146.     }
  147.     if (!isSatisfied)
  148.     {
  149.         std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  150.         send(fds[numberOfSocket].fd, wrongCommandString.data(), wrongCommandString.size(), 0);
  151.     }
  152. }
  153.  
  154. void processDataUDP(std::string data, int numberOfSocket)
  155. {
  156.     bool isSatisfied = false;
  157.     data.erase(data.begin() + data.size() - 1, data.begin() + data.size());
  158.     int spacePos = data.find_first_of(" ");
  159.     std::string command, parameter;
  160.     if (spacePos == std::string::npos)
  161.     {
  162.         command = data;
  163.         parameter = "";
  164.     }
  165.     else
  166.     {
  167.         command = data.substr(0, spacePos);
  168.         parameter = data.substr(spacePos + 1, data.size() - spacePos - 1);
  169.     }
  170.     if (command == ECHO_COMMAND)
  171.     {
  172.         if (parameter != "")
  173.         {
  174.             sendto(sd, parameter.data(), parameter.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  175.         }
  176.         else
  177.         {
  178.             std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  179.             sendto(sd, wrongCommandString.data(), wrongCommandString.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  180.         }
  181.         isSatisfied = true;
  182.     }
  183.     if (command == TIME_COMMAND)
  184.     {
  185.         if (parameter == "")
  186.         {
  187.             auto timeC = std::chrono::system_clock::now();
  188.  
  189.             std::time_t time_conv = std::chrono::system_clock::to_time_t(timeC);
  190.             std::string timeStr(std::ctime(&time_conv));
  191.             timeStr.erase(timeStr.begin() + timeStr.size() - 1, timeStr.begin() + timeStr.size());
  192.             sendto(sd, timeStr.data(), timeStr.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  193.         }
  194.         else
  195.         {
  196.             std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  197.             sendto(sd, wrongCommandString.data(), wrongCommandString.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  198.         }
  199.         isSatisfied = true;
  200.     }
  201.     if (command == DOWNLOAD_COMMAND)
  202.     {
  203.         std::ifstream fin;
  204.         fin.open(parameter, std::ios::binary | std::ios::in);
  205.         if (!fin.is_open())
  206.         {
  207.             std::string noFileMessage = NO_SUCH_FILE_MESSAGE;
  208.             sendto(sd, noFileMessage.data(), noFileMessage.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  209.         }
  210.         else
  211.         {
  212.             std::string fileFoundMessage = FILE_FOUND_MESSAGE;
  213.             sendto(sd, fileFoundMessage.data(), fileFoundMessage.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  214.             fin.ignore(std::numeric_limits<std::streamsize>::max());
  215.             std::streamsize length = fin.gcount();
  216.             fin.clear();
  217.             fin.seekg(0, std::ios_base::beg);
  218.             size_t lengthFile = length;
  219.             char *fileData = (char *)malloc(sizeof(char) * lengthFile);
  220.             fin.read(fileData, lengthFile);
  221.             sBuffers[numberOfSocket].outBuf = fileData;
  222.             sBuffers[numberOfSocket].outBufPos = 0;
  223.             sBuffers[numberOfSocket].outBufLength = lengthFile;
  224.             sendto(sd, &lengthFile, sizeof(size_t), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  225.         }
  226.         fin.close();
  227.         isSatisfied = true;
  228.     }
  229.     if (!isSatisfied)
  230.     {
  231.         std::string wrongCommandString = WRONG_COMMAND_MESSAGE;
  232.         sendto(sd, wrongCommandString.data(), wrongCommandString.size(), 0, (struct sockaddr *)&clientAddresses[numberOfSocket], sizeof(clientAddresses[numberOfSocket]));
  233.     }
  234. }
  235.  
  236. void readToBuffer(int numberOfSocket)
  237. {
  238.     char buffer[BUFFER_SIZE];
  239.     memset(buffer, 0, BUFFER_SIZE);
  240.     int rc = read(fds[numberOfSocket].fd, buffer, BUFFER_SIZE);
  241.     if (rc == 0)
  242.     {
  243.         pollhup = true;
  244.         return;
  245.     }
  246.     std::string bufferString(buffer);
  247.     sBuffers[numberOfSocket - 1].inbuf += bufferString;
  248.     size_t pos = bufferString.find_first_of('\n');
  249.     if (pos != std::string::npos)
  250.     {
  251.         processData(sBuffers[numberOfSocket - 1].inbuf, numberOfSocket);
  252.         sBuffers[numberOfSocket - 1].inbuf.clear();
  253.     }
  254. }
  255.  
  256. void *routine(void *args)
  257. {
  258.     int num = *((int *)args);
  259.     while (true)
  260.     {
  261.         int count = poll(fds.data() + num, 1, 0);
  262.         if (count > 0)
  263.         {
  264.             switch (fds[num].revents)
  265.             {
  266.             case POLLIN:
  267.                 readToBuffer(num);
  268.                 break;
  269.             case POLLOUT:
  270.             case POLLRDHUP:
  271.             case POLLERR:
  272.             case POLLHUP:
  273.                 std::cout << "asdf" << std::endl;
  274.                 break;
  275.             case POLLNVAL:
  276.             case POLLRDNORM:
  277.             case POLLWRBAND:
  278.                 break;
  279.  
  280.             default:
  281.                 std::cout << "Aboba" << std::endl;
  282.                 break;
  283.             }
  284.             fds[num].revents = 0;
  285.  
  286.             if (pollhup)
  287.             {
  288.                 fds.erase(fds.begin() + num, fds.begin() + num + 1);
  289.                 sBuffers.erase(sBuffers.begin() + num - 1, sBuffers.begin() + num);
  290.                 pollhup = false;
  291.                 return NULL;
  292.             }
  293.         }
  294.         int i = num - 1;
  295.         if (sBuffers[i].outBufPos == -1)
  296.         {
  297.             continue;
  298.         }
  299.         size_t bytesToSend;
  300.         if (sBuffers[i].outBufPos + BUFFER_SIZE >= sBuffers[i].outBufLength)
  301.         {
  302.             bytesToSend = sBuffers[i].outBufLength - sBuffers[i].outBufPos;
  303.         }
  304.         else
  305.         {
  306.             bytesToSend = BUFFER_SIZE;
  307.         }
  308.         send(fds[i + 1].fd, sBuffers[i].outBuf + sBuffers[i].outBufPos, bytesToSend, 0);
  309.         sBuffers[i].outBufPos += bytesToSend;
  310.         if (sBuffers[i].outBufPos == sBuffers[i].outBufLength)
  311.         {
  312.             sBuffers[i].outBufPos = -1;
  313.             sBuffers[i].outBufLength = -1;
  314.             free(sBuffers[i].outBuf);
  315.         }
  316.     }
  317.  
  318.     return NULL;
  319. }
  320.  
  321. void processEventsASYNC()
  322. {
  323.     if (fds[0].revents == POLLIN)
  324.     {
  325.         struct sockaddr_in clientAddress;
  326.         memset(&clientAddress, 0, sizeof(clientAddress));
  327.         int clientAddressSize = sizeof(clientAddress);
  328.         int sdClient = accept(sd, (struct sockaddr *)&clientAddress, (socklen_t *)&clientAddressSize);
  329.         if (sdClient < 0)
  330.         {
  331.             std::cout << "Can not accept connection" << std::endl;
  332.         }
  333.         else
  334.         {
  335.             struct pollfd client;
  336.             memset(&client, 0, sizeof(client));
  337.             client.fd = sdClient;
  338.             client.events = POLLIN;
  339.             fds.push_back(client);
  340.             struct buffers bufs;
  341.             bufs.outBufPos = -1;
  342.             bufs.outBufLength = -1;
  343.             sBuffers.push_back(bufs);
  344.             int *num = (int *)malloc(sizeof(int));
  345.             *num = fds.size() - 1;
  346.             pthread_create(&threads[lastThread++], 0, routine, (void *)num);
  347.         }
  348.     }
  349. }
  350.  
  351. void processEvents()
  352. {
  353.     if (fds[0].revents == POLLIN)
  354.     {
  355.         struct sockaddr_in clientAddress;
  356.         memset(&clientAddress, 0, sizeof(clientAddress));
  357.         int clientAddressSize = sizeof(clientAddress);
  358.         int sdClient = accept(sd, (struct sockaddr *)&clientAddress, (socklen_t *)&clientAddressSize);
  359.         if (sdClient < 0)
  360.         {
  361.             std::cout << "Can not accept connection" << std::endl;
  362.         }
  363.         else
  364.         {
  365.             struct pollfd client;
  366.             memset(&client, 0, sizeof(client));
  367.             client.fd = sdClient;
  368.             client.events = POLLIN;
  369.             fds.push_back(client);
  370.             struct buffers bufs;
  371.             bufs.outBufPos = -1;
  372.             bufs.outBufLength = -1;
  373.             sBuffers.push_back(bufs);
  374.         }
  375.     }
  376.     for (int i = 1; i < fds.size(); i++)
  377.     {
  378.         switch (fds[i].revents)
  379.         {
  380.         case POLLIN:
  381.             readToBuffer(i);
  382.             break;
  383.         case POLLOUT:
  384.         case POLLRDHUP:
  385.         case POLLERR:
  386.         case POLLHUP:
  387.             std::cout << "asdf" << std::endl;
  388.             break;
  389.         case POLLNVAL:
  390.         case POLLRDNORM:
  391.         case POLLWRBAND:
  392.             break;
  393.  
  394.         default:
  395.             std::cout << "Aboba" << std::endl;
  396.             break;
  397.         }
  398.         fds[i].revents = 0;
  399.  
  400.         if (pollhup)
  401.         {
  402.             fds.erase(fds.begin() + i, fds.begin() + i + 1);
  403.             sBuffers.erase(sBuffers.begin() + i - 1, sBuffers.begin() + i);
  404.             i--;
  405.             pollhup = false;
  406.         }
  407.     }
  408. }
  409.  
  410. void *routineUDP(void *args)
  411. {
  412.     int num = *((int *)args);
  413.     while (true)
  414.     {
  415.         size_t pos = sBuffers[num].inbuf.find_first_of('\n');
  416.         if (pos != std::string::npos)
  417.         {
  418.             if (sBuffers[num].inbuf == QUIT_MESSAGE)
  419.             {
  420.                 clientAddresses.erase(clientAddresses.begin() + num, clientAddresses.begin() + num + 1);
  421.                 sBuffers.erase(sBuffers.begin() + num, sBuffers.begin() + num + 1);
  422.                 return NULL;
  423.             }
  424.             processDataUDP(sBuffers[num].inbuf, num);
  425.             sBuffers[num].inbuf.clear();
  426.         }
  427.         int i = num;
  428.         if (sBuffers[i].outBufPos == -1)
  429.         {
  430.             continue;
  431.         }
  432.         size_t bytesToSend;
  433.         if (sBuffers[i].outBufPos + BUFFER_SIZE >= sBuffers[i].outBufLength)
  434.         {
  435.             bytesToSend = sBuffers[i].outBufLength - sBuffers[i].outBufPos;
  436.         }
  437.         else
  438.         {
  439.             bytesToSend = BUFFER_SIZE;
  440.         }
  441.         sendto(sd, sBuffers[i].outBuf + sBuffers[i].outBufPos, bytesToSend, 0, (struct sockaddr *)&clientAddresses[i], sizeof(clientAddresses[i]));
  442.         sBuffers[i].outBufPos += bytesToSend;
  443.         if (sBuffers[i].outBufPos == sBuffers[i].outBufLength)
  444.         {
  445.             sBuffers[i].outBufPos = -1;
  446.             sBuffers[i].outBufLength = -1;
  447.             free(sBuffers[i].outBuf);
  448.         }
  449.     }
  450.     return NULL;
  451. }
  452.  
  453. void putClientAddressAndMessageASYNC(struct sockaddr_in address, std::string message)
  454. {
  455.     bool found = false;
  456.     for (int i = 0; i < clientAddresses.size(); i++)
  457.     {
  458.         char storingAddress[256];
  459.         char incomingAddress[256];
  460.         inet_ntop(AF_INET, &(address.sin_addr), incomingAddress, 256);
  461.         inet_ntop(AF_INET, &(clientAddresses[i].sin_addr), storingAddress, 256);
  462.         if (strcmp(storingAddress, incomingAddress) == 0)
  463.         {
  464.             found = true;
  465.             sBuffers[i].inbuf += message;
  466.  
  467.             break;
  468.         }
  469.     }
  470.     if (!found)
  471.     {
  472.         clientAddresses.push_back(address);
  473.         struct buffers b;
  474.         b.outBufLength = -1;
  475.         b.outBufPos = -1;
  476.         sBuffers.push_back(b);
  477.         sBuffers[sBuffers.size() - 1].inbuf += message;
  478.         int *num = (int *)malloc(sizeof(int));
  479.         *num = clientAddresses.size() - 1;
  480.         pthread_create(&threads[lastThread++], 0, routineUDP, (void *)num);
  481.     }
  482. }
  483.  
  484. void putClientAddressAndMessage(struct sockaddr_in address, std::string message)
  485. {
  486.     bool found = false;
  487.     if (message == QUIT_MESSAGE)
  488.     {
  489.         found = true;
  490.     }
  491.     for (int i = 0; i < clientAddresses.size(); i++)
  492.     {
  493.         char storingAddress[256];
  494.         char incomingAddress[256];
  495.         inet_ntop(AF_INET, &(address.sin_addr), incomingAddress, 256);
  496.         inet_ntop(AF_INET, &(clientAddresses[i].sin_addr), storingAddress, 256);
  497.         if (message == QUIT_MESSAGE)
  498.         {
  499.             found = true;
  500.         }
  501.         if (strcmp(storingAddress, incomingAddress) == 0)
  502.         {
  503.             if (message == QUIT_MESSAGE)
  504.             {
  505.                 clientAddresses.erase(clientAddresses.begin() + i, clientAddresses.begin() + i + 1);
  506.                 sBuffers.erase(sBuffers.begin() + i, sBuffers.begin() + i + 1);
  507.             }
  508.             else
  509.             {
  510.                 found = true;
  511.                 sBuffers[i].inbuf += message;
  512.                 size_t pos = sBuffers[i].inbuf.find_first_of('\n');
  513.                 if (pos != std::string::npos)
  514.                 {
  515.                     processDataUDP(sBuffers[i].inbuf, i);
  516.                     sBuffers[i].inbuf.clear();
  517.                 }
  518.             }
  519.             break;
  520.         }
  521.     }
  522.     if (!found)
  523.     {
  524.         clientAddresses.push_back(address);
  525.         struct buffers b;
  526.         b.outBufLength = -1;
  527.         b.outBufPos = -1;
  528.         sBuffers.push_back(b);
  529.         sBuffers[sBuffers.size() - 1].inbuf += message;
  530.         size_t pos = sBuffers[sBuffers.size() - 1].inbuf.find_first_of('\n');
  531.         if (pos != std::string::npos)
  532.         {
  533.             processDataUDP(sBuffers[sBuffers.size() - 1].inbuf, sBuffers.size() - 1);
  534.             sBuffers[sBuffers.size() - 1].inbuf.clear();
  535.         }
  536.     }
  537. }
  538.  
  539. void processEventsUDPASYNC()
  540. {
  541.     if (fds[0].revents == POLLIN)
  542.     {
  543.         struct sockaddr_in clientAddress;
  544.         memset(&clientAddress, 0, sizeof(clientAddress));
  545.         int clientAddressSize = sizeof(clientAddress);
  546.         char messBuf[256];
  547.         memset(messBuf, 0, 256);
  548.         recvfrom(sd, messBuf, 256, 0, (struct sockaddr *)&clientAddress, (socklen_t *)&clientAddressSize);
  549.         std::string data(messBuf);
  550.         if (data == "")
  551.         {
  552.             data.clear();
  553.             data = QUIT_MESSAGE + '\n';
  554.         }
  555.        
  556.         putClientAddressAndMessageASYNC(clientAddress, data);
  557.     }
  558. }
  559.  
  560. void processEventsUDP()
  561. {
  562.     if (fds[0].revents == POLLIN)
  563.     {
  564.         struct sockaddr_in clientAddress;
  565.         memset(&clientAddress, 0, sizeof(clientAddress));
  566.         int clientAddressSize = sizeof(clientAddress);
  567.         char messBuf[256];
  568.         memset(messBuf, 0, 256);
  569.         recvfrom(sd, messBuf, 256, 0, (struct sockaddr *)&clientAddress, (socklen_t *)&clientAddressSize);
  570.         std::string data(messBuf);
  571.         putClientAddressAndMessage(clientAddress, data);
  572.     }
  573. }
  574.  
  575. void processSend()
  576. {
  577.     for (int i = 0; i < sBuffers.size(); i++)
  578.     {
  579.         if (sBuffers[i].outBufPos == -1)
  580.         {
  581.             continue;
  582.         }
  583.         size_t bytesToSend;
  584.         if (sBuffers[i].outBufPos + BUFFER_SIZE >= sBuffers[i].outBufLength)
  585.         {
  586.             bytesToSend = sBuffers[i].outBufLength - sBuffers[i].outBufPos;
  587.         }
  588.         else
  589.         {
  590.             bytesToSend = BUFFER_SIZE;
  591.         }
  592.         send(fds[i + 1].fd, sBuffers[i].outBuf + sBuffers[i].outBufPos, bytesToSend, 0);
  593.         sBuffers[i].outBufPos += bytesToSend;
  594.         if (sBuffers[i].outBufPos == sBuffers[i].outBufLength)
  595.         {
  596.             sBuffers[i].outBufPos = -1;
  597.             sBuffers[i].outBufLength = -1;
  598.             free(sBuffers[i].outBuf);
  599.         }
  600.     }
  601. }
  602. void processSendUDP()
  603. {
  604.     for (int i = 0; i < sBuffers.size(); i++)
  605.     {
  606.         if (sBuffers[i].outBufPos == -1)
  607.         {
  608.             continue;
  609.         }
  610.         size_t bytesToSend;
  611.         if (sBuffers[i].outBufPos + BUFFER_SIZE >= sBuffers[i].outBufLength)
  612.         {
  613.             bytesToSend = sBuffers[i].outBufLength - sBuffers[i].outBufPos;
  614.         }
  615.         else
  616.         {
  617.             bytesToSend = BUFFER_SIZE;
  618.         }
  619.         sendto(sd, sBuffers[i].outBuf + sBuffers[i].outBufPos, bytesToSend, 0, (struct sockaddr *)&clientAddresses[i], sizeof(clientAddresses[i]));
  620.         sBuffers[i].outBufPos += bytesToSend;
  621.         if (sBuffers[i].outBufPos == sBuffers[i].outBufLength)
  622.         {
  623.             sBuffers[i].outBufPos = -1;
  624.             sBuffers[i].outBufLength = -1;
  625.             free(sBuffers[i].outBuf);
  626.         }
  627.     }
  628. }
  629. void startPollingUDPASYNC()
  630. {
  631.     while (true)
  632.     {
  633.         int numberOfEvents = poll(fds.data(), fds.size(), 0);
  634.         if (numberOfEvents < 0)
  635.         {
  636.             std::cout << "ERROR!" << std::endl;
  637.             exit(-1);
  638.         }
  639.         if (numberOfEvents > 0)
  640.         {
  641.             processEventsUDPASYNC();
  642.         }
  643.     }
  644. }
  645.  
  646. void startPollingUDP()
  647. {
  648.     while (true)
  649.     {
  650.         int numberOfEvents = poll(fds.data(), fds.size(), 0);
  651.         if (numberOfEvents < 0)
  652.         {
  653.             std::cout << "ERROR!" << std::endl;
  654.             exit(-1);
  655.         }
  656.         if (numberOfEvents > 0)
  657.         {
  658.             processEventsUDP();
  659.         }
  660.         processSendUDP();
  661.     }
  662. }
  663. void startPollingASYNC()
  664. {
  665.     while (true)
  666.     {
  667.         int numberOfEvents = poll(fds.data(), 1, 0);
  668.         if (numberOfEvents < 0)
  669.         {
  670.             std::cout << "ERROR!" << std::endl;
  671.             exit(-1);
  672.         }
  673.         if (numberOfEvents > 0)
  674.         {
  675.             processEventsASYNC();
  676.         }
  677.     }
  678. }
  679.  
  680. void startPolling()
  681. {
  682.     while (true)
  683.     {
  684.         int numberOfEvents = poll(fds.data(), fds.size(), 0);
  685.         if (numberOfEvents < 0)
  686.         {
  687.             std::cout << "ERROR!" << std::endl;
  688.             exit(-1);
  689.         }
  690.         if (numberOfEvents > 0)
  691.         {
  692.             processEvents();
  693.         }
  694.         processSend();
  695.     }
  696. }
  697.  
  698. int main()
  699. {
  700.     configureServer();
  701.  
  702.     int choice;
  703.     std::cout << "Choose mode:" << std::endl;
  704.     std::cout << "1. Sync\n2. Async\n";
  705.     std::cin >> choice;
  706.     switch (choice)
  707.     {
  708.     case 1:
  709.         if (SOCKET_TYPE == SOCK_STREAM)
  710.         {
  711.             startPolling();
  712.         }
  713.         else
  714.         {
  715.             startPollingUDP();
  716.         }
  717.         break;
  718.     case 2:
  719.         if (SOCKET_TYPE == SOCK_STREAM)
  720.         {
  721.             startPollingASYNC();
  722.         }
  723.         else
  724.         {
  725.             startPollingUDPASYNC();
  726.         }
  727.         break;
  728.     default:
  729.         std::cout << "Wrong choice" << std::endl;
  730.     }
  731.  
  732.     close(sd);
  733. }
Advertisement
Add Comment
Please, Sign In to add comment