Files
TCP_SERVER_WIN_LIN/tcp_server.cpp
2019-08-02 14:24:58 +02:00

266 lines
6.5 KiB
C++

#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<uint16_t>(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<struct sockaddr *>(&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<struct sockaddr *>(&clientAddresse), reinterpret_cast<socklen_t*>(&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<in_addr*>(record->h_addr) );
/*if(record == nullptr) {
//std::cout << "Devize '"<< name <<"' is unavailable." << std::endl;
return "-1";
}
struct in_addr * address = reinterpret_cast<in_addr*>(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<long>(buffer_size) )
buffer[static_cast<size_t>(recviedBytes)] = '\0';
else if (/*Buffer ist Voll*/ recviedBytes == static_cast<long>(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<size_t *>( 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);
}