#include "tcp_server.h" TCP_SERVER::TCP_SERVER() : serverSocket(-1), port(-1) { sizeof_sockaddr_in = sizeof(struct sockaddr_in); #ifdef Windows WSADATA wsaData; // Initialize Winsock int iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed with error: %d\n", iResult); exit(33); } #else signal(SIGPIPE, SIG_IGN); #endif } TCP_SERVER::~TCP_SERVER() { //close accept socket shutdownAccpetSocketIfItIsConnected(); #ifdef Windows //cleanup winsocks WSACleanup(); #endif } int TCP_SERVER::start(int port, int maxWaitingQueque) { if(serverSocket != -1) { std::cerr << "Error: Already started." << std::endl; return 21; } if((port > 65535) || (port < 2000)){ std::cerr << "Please enter a port number between 2000 - 65535, not: " << port << std::endl; return 1; } else std::cerr << " > Port: " << port << std::endl; //setup Server memset(&serverAddresse, 0, sizeof (serverAddresse)); serverAddresse.sin_family = AF_INET; serverAddresse.sin_addr.s_addr = INADDR_ANY; serverAddresse.sin_port = htons( static_cast(port) ); //Create socket serverSocket = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP); if (serverSocket == -1) { perror("Could not create socket"); return 3; } else std::cerr << " > Create Socket: OK" << std::endl; // Bind if (bind(serverSocket, reinterpret_cast(&serverAddresse), sizeof(serverAddresse)) == -1) { perror("bind failed. Error"); shutdownAccpetSocketIfItIsConnected(); return 4; } else std::cerr << " > Bind: OK" << std::endl; //Make Port Visible as Server + max 3 waiting-snake if(listen(serverSocket, maxWaitingQueque) == -1) { perror("Listen failed"); serverSocket= -1; shutdownAccpetSocketIfItIsConnected(); return 5; } else std::cerr << " > listen: OK" << std::endl; //everything ok: return 0; } int TCP_SERVER::acceptClient(CLIENT &client) { if(serverSocket == -1) { std::cerr << "Can't accept client when Accept socket isn't started." << std::endl; return 109; } sockaddr_in clientAddresse; int clientSocket = accept(serverSocket, reinterpret_cast(&clientAddresse), reinterpret_cast(&sizeof_sockaddr_in)); if (clientSocket < 0) { perror("Accept failed"); shutdownAccpetSocketIfItIsConnected(); return 116; } else { client.setAddress(clientSocket, clientAddresse); return 0; } } void TCP_SERVER::shutdownAccpetSocketIfItIsConnected() { if(serverSocket == -1) return; #ifdef Windows if( closesocket(this->serverSocket) != 0) #else if( close(this->serverSocket) != 0) #endif perror("Close Socket failed."); this->serverSocket = -1; this->port = -1; this->serverAddresse = sockaddr_in(); return; } int TCP_SERVER::getServerSocket() { return this->serverSocket; } int TCP_SERVER::getPort() { return this->port; } bool TCP_SERVER::isStarted() { return ((this->serverSocket == -1) ? false : true); } std::string TCP_SERVER::getIpByName(std::string name) { struct hostent * record = gethostbyname(name.c_str()); return (record == nullptr) ? "-1" : inet_ntoa( *reinterpret_cast(record->h_addr) ); /*if(record == nullptr) { //std::cout << "Devize '"<< name <<"' is unavailable." << std::endl; return "-1"; } struct in_addr * address = reinterpret_cast(record->h_addr); return inet_ntoa(*address); */ } std::string TCP_SERVER::getHostName() { char buffer[255]; return ( gethostname(buffer, (sizeof (buffer) / sizeof (char))) == -1) ? "-1" : buffer; } CLIENT::CLIENT(size_t buffer_size) : clientSocket(-1), buffer_size(buffer_size) { buffer = new char[buffer_size]; sizeof_sockaddr_in = sizeof(struct sockaddr_in); #ifdef Windows #else signal(SIGPIPE, SIG_IGN); #endif } CLIENT::~CLIENT() { disconnectIfItIsConnected(); delete buffer; buffer = nullptr; } void CLIENT::setAddress(int socket, sockaddr_in clientAddress) { this->clientSocket = socket; this->clientAddress = clientAddress; } void CLIENT::disconnectIfItIsConnected() { if(clientSocket == -1) return; else if(shutdown(this->clientSocket, 2) != 0) perror("Shutdown Socket SD_BOTH/SHUT_RDWR == 2 failed."); #ifdef Windows if(closesocket(this->clientSocket) != 0) #else if(close(this->clientSocket) != 0) #endif perror("Close Socket failed"); this->clientSocket = -1; this->clientAddress = sockaddr_in(); return; } sockaddr_in CLIENT::getAddress() { return this->clientAddress; } int CLIENT::getSocket() { return this->clientSocket; } bool CLIENT::isConnected() { return (clientSocket == -1) ? false : true; } ssize_t CLIENT::sendMessage(std::string Message) { ssize_t sendedBytes; if( (sendedBytes = send(this->clientSocket, Message.c_str(), Message.length(), 0 /*MSG_NOSIGNAL*/ )) == -1) { perror("Send failed"); this->disconnectIfItIsConnected(); return -1; } else { return sendedBytes; } } ssize_t CLIENT::recvMessage(std::string &Buffer, bool peek) { ssize_t recviedBytes; if( ( recviedBytes = recv(this->clientSocket, buffer, buffer_size, ( (peek) ? MSG_PEEK : 0 )) ) == 0) { std::cerr << "Connection closed." << std::endl; this->disconnectIfItIsConnected(); return -1; } else if (recviedBytes < 0) { perror("Recv failed"); this->disconnectIfItIsConnected(); return -1; } else { if( recviedBytes < static_cast(buffer_size) ) buffer[static_cast(recviedBytes)] = '\0'; else if (/*Buffer ist Voll*/ recviedBytes == static_cast(buffer_size)) { std::cout << "Buffer voll" << std::endl; } else { std::cerr << "Recived more bytes than the buffer is big at one time." << std::endl; this->disconnectIfItIsConnected(); return -1; } } Buffer = buffer; //std::cout << *reinterpret_cast( buffer )<< std::endl; return recviedBytes; } ssize_t CLIENT::sendToClient(const void *buffer, size_t __n, int flag) { return send(this->clientSocket, buffer, __n, flag); } ssize_t CLIENT::recvFromClient(void *buffer, size_t __n, int flag) { return recv(this->clientSocket, buffer, __n, flag); }