Advertisement
Nickel59

Untitled

Dec 6th, 2024 (edited)
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.34 KB | None | 0 0
  1. #undef UNICODE
  2.  
  3. #define WIN32_LEAN_AND_MEAN
  4.  
  5. #include <inttypes.h>
  6. #include <stdbool.h>
  7. #include <stdint.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <vcruntime.h>
  12. #include <windows.h>
  13. #include <winsock2.h>
  14. #include <ws2tcpip.h>
  15.  
  16. // Need to link with Ws2_32.lib
  17. #pragma comment(lib, "Ws2_32.lib")
  18. // #pragma comment (lib, "Mswsock.lib")
  19.  
  20. #define DEFAULT_BUFLEN 512
  21. #define DEFAULT_PORT "27015"
  22.  
  23. #define lengthof(x) (sizeof(x) / sizeof((x)[0]))
  24.  
  25. void *safemalloc(size_t size) {
  26.   void *block = malloc(size);
  27.   if (!block) {
  28.     (void)fputs("Memory allocation has failed.", stderr);
  29.     abort();
  30.   }
  31.   return block;
  32. }
  33.  
  34. uint64_t abs64(int64_t integer) { return integer < 0 ? -(uint64_t)integer : integer; }
  35.  
  36. typedef struct {
  37.   int64_t integer;
  38.   const char *error;
  39. } StringToIntResult;
  40. StringToIntResult *stringToInt(const char *string) {
  41.   StringToIntResult *result = safemalloc(sizeof(StringToIntResult));
  42.   if (!string) {
  43.     *result = (StringToIntResult){0, "Passed NULL."};
  44.     return result;
  45.   }
  46.   if (string[0] == '\0') {
  47.     *result = (StringToIntResult){0, "Invalid string."};
  48.     return result;
  49.   }
  50.   bool startsWithNegativeSign = (string[0] == '-');
  51.   if (startsWithNegativeSign) {
  52.     string = string + 1;
  53.   }
  54.   uint64_t maxInt = abs64(startsWithNegativeSign ? INT64_MIN : INT64_MAX);
  55.   uint8_t maxDigitNumber = snprintf( // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  56.       NULL, 0, "%" PRIu64, maxInt);
  57.   size_t stringLength = strlen(string);
  58.   if (stringLength == 0 || string[0] == '0' || stringLength > maxDigitNumber) {
  59.     *result = (StringToIntResult){0, "Invalid string."};
  60.     return result;
  61.   }
  62.   for (uint32_t i = 0; i < stringLength; ++i) {
  63.     if (string[i] < '0' || string[i] > '9') {
  64.       *result = (StringToIntResult){0, "The string contains non numerical characters."};
  65.       return result;
  66.     }
  67.   }
  68.   if (stringLength == maxDigitNumber) {
  69.     char *maxString = safemalloc(maxDigitNumber + 1);
  70.     (void)snprintf(maxString, // NOLINT(clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling)
  71.                    maxDigitNumber + 1, "%" PRIu64, maxInt);
  72.     for (uint32_t i = 0; i < stringLength; ++i) {
  73.       if (string[i] > maxString[i]) {
  74.         free(maxString);
  75.         *result = (StringToIntResult){0, "The resulting integer is too large."};
  76.         return result;
  77.       }
  78.     }
  79.     free(maxString);
  80.   }
  81.   int64_t integer = strtoll(string, NULL, 10);
  82.   if (startsWithNegativeSign) {
  83.     integer = -integer;
  84.   }
  85.   *result = (StringToIntResult){integer, NULL};
  86.   return result;
  87. }
  88.  
  89. int __cdecl main(void) {
  90.   WSADATA wsaData;
  91.   int iResult;
  92.  
  93.   SOCKET ListenSocket = INVALID_SOCKET;
  94.   SOCKET ClientSocket = INVALID_SOCKET;
  95.  
  96.   struct addrinfo *result = NULL;
  97.   struct addrinfo hints;
  98.  
  99.   int iSendResult;
  100.   char recvbuf[DEFAULT_BUFLEN];
  101.   int recvbuflen = DEFAULT_BUFLEN;
  102.  
  103.   // Initialize Winsock
  104.   iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  105.   if (iResult != 0) {
  106.     printf("WSAStartup failed with error: %d\n", iResult);
  107.     return 1;
  108.   }
  109.  
  110.   ZeroMemory(&hints, sizeof(hints));
  111.   hints.ai_family = AF_INET;
  112.   hints.ai_socktype = SOCK_STREAM;
  113.   hints.ai_protocol = IPPROTO_TCP;
  114.   hints.ai_flags = AI_PASSIVE;
  115.  
  116.   // Resolve the server address and port
  117.   iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
  118.   if (iResult != 0) {
  119.     printf("getaddrinfo failed with error: %d\n", iResult);
  120.     WSACleanup();
  121.     return 1;
  122.   }
  123.  
  124.   // Create a SOCKET for connecting to server
  125.   ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  126.   if (ListenSocket == INVALID_SOCKET) {
  127.     printf("socket failed with error: %ld\n", WSAGetLastError());
  128.  
  129.     freeaddrinfo(result);
  130.     WSACleanup();
  131.     return 1;
  132.   }
  133.  
  134.   // Setup the TCP listening socket
  135.   iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
  136.   if (iResult == SOCKET_ERROR) {
  137.     printf("bind failed with error: %d\n", WSAGetLastError());
  138.     freeaddrinfo(result);
  139.     closesocket(ListenSocket);
  140.     WSACleanup();
  141.     return 1;
  142.   }
  143.  
  144.   freeaddrinfo(result);
  145.  
  146.   iResult = listen(ListenSocket, SOMAXCONN);
  147.   if (iResult == SOCKET_ERROR) {
  148.     printf("listen failed with error: %d\n", WSAGetLastError());
  149.     closesocket(ListenSocket);
  150.     WSACleanup();
  151.     return 1;
  152.   }
  153.  
  154.   // Accept a client socket
  155.   ClientSocket = accept(ListenSocket, NULL, NULL);
  156.   if (ClientSocket == INVALID_SOCKET) {
  157.     printf("accept failed with error: %d\n", WSAGetLastError());
  158.     closesocket(ListenSocket);
  159.     WSACleanup();
  160.     return 1;
  161.   }
  162.  
  163.   // No longer need server socket
  164.   closesocket(ListenSocket);
  165.  
  166.   // Receive until the peer shuts down the connection
  167.   int64_t sum = 0;
  168.   while (1) {
  169.     for (uint32_t i = 0; i < recvbuflen; ++i) {
  170.       recvbuf[i] = '\0';
  171.     }
  172.  
  173.     iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
  174.     if (iResult < 0) {
  175.       printf("recv failed with error: %d\n", WSAGetLastError());
  176.       closesocket(ClientSocket);
  177.       WSACleanup();
  178.       return 1;
  179.     }
  180.     if (!iResult) {
  181.       printf("Connection closing...\n");
  182.       break;
  183.     }
  184.  
  185.     FILE *fp;
  186.     fp = fopen("lr5.txt", "a+");
  187.     fprintf(fp, recvbuf);
  188.     fclose(fp);
  189.  
  190.     printf("Bytes received: %d\n", iResult);
  191.     // Echo the buffer back to the sender
  192.     char *newlinePtr = strchr(recvbuf, '\n');
  193.     if (newlinePtr) {
  194.       *newlinePtr = '\0';
  195.     }
  196.     StringToIntResult *result = stringToInt(recvbuf);
  197.     if (result->error) {
  198.       iSendResult = send(ClientSocket, "Invalid input.\n", lengthof("Invalid input.\n"), 0);
  199.     } else {
  200.       sum += result->integer;
  201.       char *buffer[50];
  202.       sprintf(buffer, "%" PRId64 "\n", sum);
  203.       iSendResult = send(ClientSocket, buffer, strlen(buffer), 0);
  204.     }
  205.     free(result);
  206.     if (iSendResult == SOCKET_ERROR) {
  207.       printf("send failed with error: %d\n", WSAGetLastError());
  208.       closesocket(ClientSocket);
  209.       WSACleanup();
  210.       return 1;
  211.     }
  212.     printf("Bytes sent: %d\n", iSendResult);
  213.   }
  214.  
  215.   // shutdown the connection since we're done
  216.   iResult = shutdown(ClientSocket, SD_SEND);
  217.   if (iResult == SOCKET_ERROR) {
  218.     printf("shutdown failed with error: %d\n", WSAGetLastError());
  219.     closesocket(ClientSocket);
  220.     WSACleanup();
  221.     return 1;
  222.   }
  223.  
  224.   // cleanup
  225.   closesocket(ClientSocket);
  226.   WSACleanup();
  227.  
  228.   return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement