Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Server.h"
- #undef UNICODE
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <stdlib.h>
- #include <stdio.h>
- #pragma comment(lib, "Ws2_32.lib")
- #define DEFAULT_PORT "27015"
- #define DEFAULT_BUFLEN 512
- Server::Server() {}
- void Server::Initialize() {
- // WSADATA structure contains info about the sockets implementation. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms741563(v=vs.85).aspx
- WSADATA wsaData;
- int iResult;
- // Initialize Winsock
- // WSAStartup initiates WS2_32.dll
- iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (iResult != 0) {
- printf("WSAStartup failed: %d\n", iResult);
- return;
- }
- // An addrinfo holds info about the host's address. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737530(v=vs.85).aspx
- struct addrinfo *result = NULL, *ptr = NULL, hints;
- // Zero out the memory so that we don't have any nasty surprises.
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_INET; // IPv4
- hints.ai_socktype = SOCK_STREAM; // Sequenced two-way communication.
- hints.ai_protocol = IPPROTO_TCP; // Unsure about this one. Reccomended in documentation, however I wasn't able to decipher the description.
- hints.ai_flags = AI_PASSIVE; // The socket will be bound.
- // Resolve the local address & port that this server will be using.
- iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
- if (iResult != 0) {
- printf("getaddrinfo failed: %d\n", iResult);
- WSACleanup();
- return;
- }
- // Create a socket to listen for new connections.
- SOCKET listenSocket = INVALID_SOCKET;
- // 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
- listenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
- // Check for errors
- if (listenSocket == INVALID_SOCKET) {
- printf("Error at socket(): %ld\n", WSAGetLastError());
- WSACleanup();
- return;
- }
- // Set up the TCP listening socket.
- // Bind associates a local address with a socket. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx
- iResult = bind(listenSocket, result->ai_addr, (int)result->ai_addrlen);
- if (iResult == SOCKET_ERROR) {
- printf("Failed to bind. Error: %d\n", WSAGetLastError());
- freeaddrinfo(result); // Frees up the memory that getaddrinfo() was using. We no longer need it reserved for that purpose!
- closesocket(listenSocket);
- WSACleanup();
- return;
- }
- // Listen on a socket.
- // listen puts the passed socket into listen mode. This socket will now be constantly looking for an incoming connection.
- // 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.
- if (listen(listenSocket, SOMAXCONN) == SOCKET_ERROR) {
- printf("Listen failed with error: %ld\n", WSAGetLastError());
- closesocket(listenSocket);
- WSACleanup();
- return;
- }
- // Accepting a connection
- SOCKET clientSocket;
- clientSocket = INVALID_SOCKET;
- // Accept a client socket
- // accept permits an incoming connection attempt on a socket.
- clientSocket = accept(listenSocket, NULL, NULL);
- if (clientSocket == INVALID_SOCKET) {
- printf("accept failed: %d\n", WSAGetLastError());
- closesocket(listenSocket);
- WSACleanup();
- return;
- }
- char recvbuf[DEFAULT_BUFLEN];
- int iSendResult;
- int recvbuflen = DEFAULT_BUFLEN;
- // Recieve until the peer shuts down the connection.
- do {
- // recv (ie recieve) recieves data from a connected socket. See: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
- iResult = recv(clientSocket, recvbuf, recvbuflen, 0);
- if (iResult > 0) {
- printf("Bytes recieved: %d\n", iResult);
- // Let's echo the buffer back to the sender.
- // 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
- iSendResult = send(clientSocket, recvbuf, iResult, 0);
- if (iSendResult == SOCKET_ERROR) {
- printf("send failed: %d\n", WSAGetLastError());
- closesocket(clientSocket);
- WSACleanup();
- return;
- }
- // printf("Bytes sent: %d\n", iSendResult);
- }
- else if (iResult == 0) {
- printf("Connection closing...\n");
- }
- else {
- printf("recv failed: %d\n", WSAGetLastError());
- closesocket(clientSocket);
- WSACleanup();
- return;
- }
- } while (iResult > 0);
- // Shut down the send half of the connection since no more data will be sent!
- // 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.
- iResult = shutdown(clientSocket, SD_SEND);
- if (iResult == SOCKET_ERROR) {
- printf("shutdown failed: %d\n", WSAGetLastError());
- closesocket(clientSocket);
- WSACleanup();
- return;
- }
- // Cleanup
- closesocket(clientSocket); // Close the socket.
- WSACleanup(); // Clean up and release reserved resources.
- return;
- }
Advertisement
Add Comment
Please, Sign In to add comment