278 lines
6.8 KiB
C++
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();
|
|
}
|