#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;
}