266 lines
6.5 KiB
C++
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);
|
|
}
|
|
|