slimabob

server.cpp

Jan 18th, 2018
187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.09 KB | None | 0 0
  1. #include "Server.h"
  2.  
  3. #undef UNICODE
  4.  
  5. #define WIN32_LEAN_AND_MEAN
  6.  
  7. #include <windows.h>
  8. #include <winsock2.h>
  9. #include <ws2tcpip.h>
  10. #include <stdlib.h>
  11. #include <stdio.h>
  12.  
  13. #pragma comment(lib, "Ws2_32.lib")
  14.  
  15. #define DEFAULT_PORT "27015"
  16. #define DEFAULT_BUFLEN 512
  17.  
  18. Server::Server() {}
  19.  
  20. void Server::Initialize() {
  21.  
  22.     // WSADATA structure contains info about the sockets implementation. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms741563(v=vs.85).aspx
  23.     WSADATA wsaData;
  24.  
  25.     int iResult;
  26.  
  27.     // Initialize Winsock
  28.     // WSAStartup initiates WS2_32.dll
  29.     iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  30.     if (iResult != 0) {
  31.         printf("WSAStartup failed: %d\n", iResult);
  32.         return;
  33.     }
  34.  
  35.     // An addrinfo holds info about the host's address. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737530(v=vs.85).aspx
  36.     struct addrinfo *result = NULL, *ptr = NULL, hints;
  37.  
  38.     // Zero out the memory so that we don't have any nasty surprises.
  39.     ZeroMemory(&hints, sizeof(hints));
  40.     hints.ai_family = AF_INET;          // IPv4
  41.     hints.ai_socktype = SOCK_STREAM;    // Sequenced two-way communication.
  42.     hints.ai_protocol = IPPROTO_TCP;    // Unsure about this one. Reccomended in documentation, however I wasn't able to decipher the description.
  43.     hints.ai_flags = AI_PASSIVE;        // The socket will be bound.
  44.  
  45.     // Resolve the local address & port that this server will be using.
  46.     iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
  47.     if (iResult != 0) {
  48.         printf("getaddrinfo failed: %d\n", iResult);
  49.         WSACleanup();
  50.         return;
  51.     }
  52.  
  53.     // Create a socket to listen for new connections.
  54.     SOCKET listenSocket = INVALID_SOCKET;
  55.  
  56.     // The socket function is what actually creates & initializes the socket. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740506(v=vs.85).aspx
  57.     listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  58.  
  59.     // Check for errors
  60.     if (listenSocket == INVALID_SOCKET) {
  61.         printf("Error at socket(): %ld\n", WSAGetLastError());
  62.         WSACleanup();
  63.         return;
  64.     }
  65.  
  66.     // Set up the TCP listening socket.
  67.     // Bind associates a local address with a socket. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx
  68.     iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen);
  69.     if (iResult == SOCKET_ERROR) {
  70.         printf("Failed to bind. Error: %d\n", WSAGetLastError());
  71.         freeaddrinfo(result);       // Frees up the memory that getaddrinfo() was using. We no longer need it reserved for that purpose!
  72.         closesocket(listenSocket);
  73.         WSACleanup();
  74.         return;
  75.     }
  76.  
  77.     // Listen on a socket.
  78.     // listen puts the passed socket into listen mode. This socket will now be constantly looking for an incoming connection.
  79.     // The second entry is for max connections. We're using SOMAXCONN for now, which is substantially more than we need. It doesn't hurt to have it this high however.
  80.     if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
  81.         printf("Listen failed with error: %ld\n", WSAGetLastError());
  82.         closesocket(listenSocket);
  83.         WSACleanup();
  84.         return;
  85.     }
  86.  
  87.     // Accepting a connection
  88.     SOCKET clientSocket;
  89.  
  90.     clientSocket = INVALID_SOCKET;
  91.  
  92.     // Accept a client socket
  93.     // accept permits an incoming connection attempt on a socket.
  94.     clientSocket = accept(listenSocket, NULL, NULL);
  95.     if (clientSocket == INVALID_SOCKET) {
  96.         printf("accept failed: %d\n", WSAGetLastError());
  97.         closesocket(listenSocket);
  98.         WSACleanup();
  99.         return;
  100.     }
  101.  
  102.  
  103.     char recvbuf[DEFAULT_BUFLEN];
  104.     int iSendResult;
  105.     int recvbuflen = DEFAULT_BUFLEN;
  106.  
  107.     // Recieve until the peer shuts down the connection.
  108.     do {
  109.  
  110.         // recv (ie recieve) recieves data from a connected socket. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
  111.         iResult = recv(clientSocket, recvbuf, recvbuflen, 0);
  112.         if (iResult > 0) {
  113.             printf("Bytes recieved: %d\n", iResult);
  114.  
  115.             // Let's echo the buffer back to the sender.
  116.             // send, similar to recv, interacts with a connected socket. It sends data. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740149(v=vs.85).aspx
  117.             iSendResult = send(clientSocket, recvbuf, iResult, 0);
  118.             if (iSendResult == SOCKET_ERROR) {
  119.                 printf("send failed: %d\n", WSAGetLastError());
  120.                 closesocket(clientSocket);
  121.                 WSACleanup();
  122.                 return;
  123.             }
  124.  
  125.             // printf("Bytes sent: %d\n", iSendResult);
  126.         }
  127.         else if (iResult == 0) {
  128.             printf("Connection closing...\n");
  129.         }
  130.         else {
  131.             printf("recv failed: %d\n", WSAGetLastError());
  132.             closesocket(clientSocket);
  133.             WSACleanup();
  134.             return;
  135.         }
  136.     } while (iResult > 0);
  137.  
  138.     // Shut down the send half of the connection since no more data will be sent!
  139.     // shutdown disables aspects of a socket. In this case we're disabling the send aspect of the client socket. It can automatically re-enable if necessary.
  140.     iResult = shutdown(clientSocket, SD_SEND);
  141.     if (iResult == SOCKET_ERROR) {
  142.         printf("shutdown failed: %d\n", WSAGetLastError());
  143.         closesocket(clientSocket);
  144.         WSACleanup();
  145.         return;
  146.     }
  147.  
  148.     // Cleanup
  149.     closesocket(clientSocket);      // Close the socket.
  150.     WSACleanup();                   // Clean up and release reserved resources.
  151.     return;
  152. }
Advertisement
Add Comment
Please, Sign In to add comment