#include "networking.h" #include <WS2tcpip.h> #include <iostream> #include "constants.h" #pragma comment(lib, "ws2_32.lib") #define PORT 54000 SOCKET sock = INVALID_SOCKET; SOCKET client_socket = INVALID_SOCKET; int address_family = AF_INET; int type = SOCK_STREAM; int protocol = 0; // packet definitions GLfloat fail[IN_OUT_BUFF_SIZE] = { -1 }; GLfloat move[IN_OUT_BUFF_SIZE] = { 0 }; GLfloat shoot[IN_OUT_BUFF_SIZE] = { 1 }; string Network::printLocalIPAddress() { char host[NI_MAXHOST]; if (gethostname(host, sizeof(host)) == SOCKET_ERROR) { cout << "Error getting hostname. Quitting" << endl; return ""; } addrinfo hints = {}; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; addrinfo* info; if (getaddrinfo(host, nullptr, &hints, &info) != 0) { cout << "Error getting local IP. Quitting" << endl; return ""; } string ipAddress; for (addrinfo* ptr = info; ptr != nullptr; ptr = ptr->ai_next) { sockaddr_in* ipv4 = (sockaddr_in*)ptr->ai_addr; char ipStr[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipv4->sin_addr, ipStr, INET_ADDRSTRLEN); cout << "Server IP: " << ipStr << endl; ipAddress = ipStr; } freeaddrinfo(info); return ipAddress; } SOCKET Network::serverSetup() { WSADATA wsData; WORD ver = MAKEWORD(2, 2); if (WSAStartup(ver, &wsData) != 0) { cout << "Winsock initialization failed!" << endl; return INVALID_SOCKET; } SOCKET listening = socket(AF_INET, SOCK_STREAM, 0); if (listening == INVALID_SOCKET) { cout << "Socket creation failed!" << endl; WSACleanup(); return INVALID_SOCKET; } sockaddr_in hint = {}; hint.sin_family = AF_INET; hint.sin_port = htons(PORT); hint.sin_addr.S_un.S_addr = INADDR_ANY; printLocalIPAddress(); if (bind(listening, (sockaddr*)&hint, sizeof(hint)) == SOCKET_ERROR) { cout << "Binding failed!" << endl; closesocket(listening); WSACleanup(); return INVALID_SOCKET; } listen(listening, SOMAXCONN); u_long mode = 1; // non blocking ioctlsocket(listening, FIONBIO, &mode); cout << "Waiting for a connection..." << endl; return listening; // not client socket } SOCKET Network::clientSetup(std::string serverIP) { WSADATA wsData; WORD ver = MAKEWORD(2, 2); if (WSAStartup(ver, &wsData) != 0) { cout << "Can't start Winsock! Quitting" << endl; return INVALID_SOCKET; } sock = socket(address_family, type, protocol); if (sock == INVALID_SOCKET) { cout << "Can't create socket, Err #" << WSAGetLastError() << endl; WSACleanup(); return INVALID_SOCKET; } sockaddr_in hint = {}; hint.sin_family = AF_INET; hint.sin_port = htons(PORT); inet_pton(AF_INET, serverIP.c_str(), &hint.sin_addr); if (connect(sock, (sockaddr*)&hint, sizeof(hint)) == SOCKET_ERROR) { cout << "Can't connect to server, Err #" << WSAGetLastError() << endl; closesocket(sock); WSACleanup(); return INVALID_SOCKET; } cout << "Connected to server! Start chatting..." << endl; return sock; } bool Network::sendData(SOCKET sock, char* buff, size_t size) { int bytesSent = send(sock, buff, static_cast<int>(size), 0); if (bytesSent == SOCKET_ERROR) { std::cout << "send failed: " << WSAGetLastError() << std::endl; closesocket(sock); WSACleanup(); return false; } return bytesSent == static_cast<int>(size); } bool Network::recvData(SOCKET sock, char* buff, size_t bufferSize, size_t& bytesReceived) { bytesReceived = recv(sock, buff, static_cast<int>(bufferSize), 0); if (bytesReceived == SOCKET_ERROR) { int err = WSAGetLastError(); if (err == WSAEWOULDBLOCK) { // no data available now, but connection is still good bytesReceived = 0; return true; } std::cout << "recv failed: " << err << std::endl; return false; } if (bytesReceived == 0) { std::cout << "Connection closed by peer." << std::endl; return false; } return true; }