Files
klingelPiServer/server_tcp_lib.cpp
Your Name 20606175bc pi
2022-03-11 17:48:08 +01:00

278 lines
6.8 KiB
C++

#include "server_tcp_lib.h"
TCP_SERVER::TCP_SERVER()
: listeningSocket(-1),
listeningPort(0),
sizeof_sockaddr_in(sizeof(struct sockaddr_in))
{
#ifdef _WIN32
// Initialize Winsock
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
exit(33);
}
#endif
#ifdef __linux
signal(SIGPIPE, SIG_IGN);
#endif
}
TCP_SERVER::~TCP_SERVER()
{
if(autoCleanUpInTheEnd && this->isListening()) {
stopListening();
#ifdef _WIN32
//cleanup winsocks
WSACleanup();
#endif
}
//if(autoCleanUpInTheEnd)
// perror("DEBUG DESTRUKTOR WARNUNG");
}
int TCP_SERVER::startListening(const unsigned short &port, const int &maxWaitingQueque, const unsigned int saddr)
{
if(listeningSocket != -1) {
setErrorMessage("Start Listening faild: Already started.");
return 1;
}
//setup Server && save port
memset(&serverAddresse, 0, sizeof (serverAddresse));
serverAddresse.sin_family = AF_INET;
serverAddresse.sin_addr.s_addr = htonl(saddr);
serverAddresse.sin_port = htons( static_cast<uint16_t>(port) );
this->listeningPort = port;
//Create socket
if ( (listeningSocket = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP)) == -1) {
setErrorMessage("Start Listening faild: Could not create the socket", true);
return 2;
// Bind
} else if (bind(listeningSocket, reinterpret_cast<struct sockaddr *>(&serverAddresse), sizeof(serverAddresse)) == -1) {
setErrorMessage("Start Listening faild: Could not bind the address to the socket", true, true);
return 3;
//Make Port Visible as Server + max 3 waiting-snake
} else if(listen(listeningSocket, maxWaitingQueque) == -1) {
setErrorMessage("Start Listening faild: Could not make the socket visible as a server", true, true);
return 5;
}
setErrorMessage("Success: Started listing for clients on port " + std::to_string(port) + ".");
return 0; //everything ok:
}
int TCP_SERVER::stopListening()
{
if(listeningSocket == -1) {
setErrorMessage("Stop Server failed: Server wasn't running.");
return -1;
}
int res;
#ifdef _WIN32
res = closesocket(listeningSocket);
#endif
#ifdef __linux
res = close(listeningSocket);
#endif
this->listeningSocket = -1;
return res;
}
bool TCP_SERVER::isListening() const
{
return (this->listeningSocket != -1);
}
int TCP_SERVER::acceptClient(CLIENT &client)
{
if(listeningSocket == -1) {
setErrorMessage("Accept client failed: Server not started.");
return 1;
}
sockaddr_in clientAddresse; //lin unsigned win not unsigend
int clientSocket = accept(listeningSocket, reinterpret_cast<struct sockaddr *>( &clientAddresse ),
#ifdef _WIN32
reinterpret_cast<int*>
#endif
#ifdef __linux
reinterpret_cast<socklen_t*>
#endif
(&sizeof_sockaddr_in) );
if (clientSocket < 0) {
setErrorMessage("Accept client failed: accept failed", true, true);
return 2;
}
client.setAddress(clientSocket, clientAddresse);
return 0;
}
std::string TCP_SERVER::getLastError() const
{
return errorMessage;
}
int TCP_SERVER::getListeningSocket() const
{
return listeningSocket;
}
unsigned short TCP_SERVER::getListeningPort() const
{
return listeningPort;
}
std::string TCP_SERVER::getIpByName(const std::string &name)
{
//struct hostent * record = gethostbyname(name.c_str());
for (int i = 0; i < 2; ++i) {
if(i == 1)
std::cout << " => Warning: Second getIpByName-Try" << std::endl;
struct hostent * record = gethostbyname(name.c_str());
if(record == nullptr) {
return "";
} else {
in_addr * iadp = reinterpret_cast<in_addr*>(record->h_addr);
if(iadp == nullptr)
continue;
else {
char * charP = inet_ntoa( *iadp );
if(charP == nullptr)
continue;
else
return charP;
}
}
}
std::cout << "getIpByName tried out" << std::endl;
return "";
//struct hostent * record = gethostbyname(name.c_str());
//return (record == nullptr) ? "" : inet_ntoa( *reinterpret_cast<in_addr*>(record->h_addr) );
}
std::string TCP_SERVER::getHostName()
{
char buffer[255];
return ( gethostname(buffer, (sizeof (buffer) / sizeof (char))) == -1) ? "" : buffer;
}
void TCP_SERVER::setErrorMessage(const std::string &txt, bool withPerrorText, bool closesocket)
{
this->errorMessage = txt + ((withPerrorText) ? ": " + std::string( std::strerror(errno) ) : "");
if(closesocket)
stopListening();
}
CLIENT::CLIENT()
: sizeof_sockaddr_in( sizeof(struct sockaddr_in) ),
clientSocket(-1)
{
#ifdef __linux
signal(SIGPIPE, SIG_IGN);
#endif
}
CLIENT::~CLIENT()
{
if(autoCleanUpInTheEnd && this->isConnected()) {
closeSocket();
//cleanup winsocks
#ifdef __WIN32
WSACleanup();
#endif
}
//if(autoCleanUpInTheEnd)
// perror("DEBUG DESTRUKTOR WARNUNG 22");
}
void CLIENT::setAddress(const int &socket, const sockaddr_in &clientAddress)
{
this->clientSocket = socket;
this->clientAddress = clientAddress;
}
int CLIENT::closeSocket()
{
if(clientSocket == -1)
return 0;
#ifdef _WIN32
if( closesocket(this->clientSocket) != 0) {
#endif
#ifdef __linux
if( close(this->clientSocket) != 0) {
#endif
setErrorMessage("Close socket failed", true);
return 1;
}
this->clientSocket = -1;
memset(&this->clientAddress, 0, sizeof (this->clientAddress));
return 0;
}
ssize_t CLIENT::send_(const char *buffer, size_t __n, int flags)
{
return send(this->clientSocket, buffer, __n, flags);
}
ssize_t CLIENT::recv_(char *buffer, size_t __n, int flags)
{
return recv(this->clientSocket, buffer, __n, flags);
}
std::string CLIENT::getLastError() const
{
return errorMessage;
}
sockaddr_in CLIENT::getAddress() const
{
return clientAddress;
}
std::string CLIENT::getIpAddress() const
{
return inet_ntoa(clientAddress.sin_addr);
}
unsigned short CLIENT::getPort() const
{
return ntohs( clientAddress.sin_port );
}
int CLIENT::getSocket() const
{
return clientSocket;
}
bool CLIENT::isConnected() const
{
return (clientSocket == -1) ? false : true;
}
void CLIENT::setErrorMessage(const std::string &txt, bool withPerrorText, bool closesocket)
{
this->errorMessage = txt + ((withPerrorText) ? ": " + std::string( std::strerror(errno) ) : "");
if(closesocket)
closeSocket();
}