Initial commit
This commit is contained in:
		
							
								
								
									
										770
									
								
								BaseCrossSocket.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										770
									
								
								BaseCrossSocket.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,770 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// BaseCrossSocket.cpp
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#include "BaseCrossSocket.h"
 | 
				
			||||||
 | 
					#include "CrossSocketPlatform.h"
 | 
				
			||||||
 | 
					#include "CrossSocket.h"
 | 
				
			||||||
 | 
					#include "CrossThreads.h"
 | 
				
			||||||
 | 
					#include "CrossThreadsHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					#include <new>
 | 
				
			||||||
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create the constructor
 | 
				
			||||||
 | 
					BaseCrossSocket::BaseCrossSocket()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _socketHandle = -1;
 | 
				
			||||||
 | 
					    _closeSignal = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize default values
 | 
				
			||||||
 | 
					    _error = "";
 | 
				
			||||||
 | 
					    _blockingMode = nonblocking;
 | 
				
			||||||
 | 
					    _timeoutSeconds = 0;
 | 
				
			||||||
 | 
					    _timeoutMicroSeconds = 0;
 | 
				
			||||||
 | 
					    _password = "";
 | 
				
			||||||
 | 
					    _threadHandler = new CrossThreadsHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #ifdef __WIN32__
 | 
				
			||||||
 | 
					        static bool firstTime = true;
 | 
				
			||||||
 | 
					        if (firstTime)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            WSAData wsaData;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if ((int i = WSAStartup(MAKEWORD(1, 1), &wsaData)) != 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                handleError(NULL, "BaseCrossSocket - WSAStartup() failed: ");
 | 
				
			||||||
 | 
					                exit(-1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // cleanup
 | 
				
			||||||
 | 
					            atexit(WSA_exit);
 | 
				
			||||||
 | 
					            firstTime = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    #endif          
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BaseCrossSocket::~BaseCrossSocket()
 | 
				
			||||||
 | 
					{	
 | 
				
			||||||
 | 
					    if (_socketHandle > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        close(_socketHandle);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::listen(int connectionLimit, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    fprintf(stderr,"This application is using: CrossSockets\n"
 | 
				
			||||||
 | 
					            "          Created by Jeroen Saey\n"
 | 
				
			||||||
 | 
					            "========================================\n"); 
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    getSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char alreadyInUse = 1;
 | 
				
			||||||
 | 
					    setsockopt(_socketHandle, SOL_SOCKET, SO_REUSEADDR, &alreadyInUse, sizeof(int));
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    if(::listen(_socketHandle, connectionLimit) == -1)
 | 
				
			||||||
 | 
					    {	
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::listen() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BaseCrossSocket* BaseCrossSocket::accept(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int remoteSocketHandle = -1;
 | 
				
			||||||
 | 
					    sockaddr remoteAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!waitRead(error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    sw_socklen_t socketSize = sizeof(sockaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((remoteSocketHandle = ::accept(_socketHandle, &remoteAddress, &socketSize)) == int(SOCKETFAIL))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::accept() error: ");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    // Check if we are in non blocking mode
 | 
				
			||||||
 | 
					    if (_blockingMode == nonblocking)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fcntl(remoteSocketHandle, F_SETFL, O_NONBLOCK);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   // Create a new class of the BaseCrossSocket
 | 
				
			||||||
 | 
					    BaseCrossSocket* clientSocket = create(remoteSocketHandle, error);
 | 
				
			||||||
 | 
					         
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    stringstream clientInformation;
 | 
				
			||||||
 | 
					    clientInformation       << ((CrossSocket*)clientSocket)->getClientAddress() << " is connected!\n"
 | 
				
			||||||
 | 
					                            << ((CrossSocket*)clientSocket)->getClientAddress() << " : " << ((CrossSocket*)clientSocket)->getClientPort() << "\n";
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    cout << clientInformation.str();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return clientSocket;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::checkPassword(BaseCrossSocket *socket)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_password.length() > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        socket->writeLine("This server is protected with a password, please insert the password now.");
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        int passwordCounter = 0;
 | 
				
			||||||
 | 
					        string givenPassword;
 | 
				
			||||||
 | 
					        while (givenPassword != _password)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Just read 50 bytes for the password
 | 
				
			||||||
 | 
					            givenPassword = socket->readLine(50);
 | 
				
			||||||
 | 
					            if (givenPassword != _password)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                socket->writeLine("Incorrect password given.");
 | 
				
			||||||
 | 
					                passwordCounter++;
 | 
				
			||||||
 | 
					                if (passwordCounter >= 5)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    socket->writeLine("Too many attempts where made to enter the correct password.");
 | 
				
			||||||
 | 
					                    socket->writeLine("Have a nice day!");
 | 
				
			||||||
 | 
					                    socket->writeLine("Disconnecting...");
 | 
				
			||||||
 | 
					                    socket->writeLine("403");
 | 
				
			||||||
 | 
					                    disconnect();
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    socket->writeLine("The password is correct. Access granted");
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::isConnected()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _socketHandle > 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::disconnect(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i = 0;
 | 
				
			||||||
 | 
					    char buffer[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::disconnect() - No connection");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // check if the client closed the connection 
 | 
				
			||||||
 | 
					    if (shutdown(_socketHandle, 1) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::disconnect() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    CrossSocketErrors crossSocketError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if we got a signal from the client that he closed the connection
 | 
				
			||||||
 | 
					    if (!_closeSignal)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        while (true)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (!waitRead(error))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            i = readLine(buffer, 256, &crossSocketError);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (i <= 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // If we do not want to wait we need to throw an error
 | 
				
			||||||
 | 
					            if (_blockingMode == noWait)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                setError(error, notReady, "BaseCrossSocket::disconnect() - We need more time, please call again");
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, crossSocketError, _error);
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reset the state
 | 
				
			||||||
 | 
					    reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    close(_socketHandle);
 | 
				
			||||||
 | 
					    _socketHandle = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    cout << "CrossSockets: Client has been disconnected!\n";
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::closeSocketHandle()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_socketHandle > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        close(_socketHandle);
 | 
				
			||||||
 | 
					        _socketHandle = -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //reset state
 | 
				
			||||||
 | 
					        reset();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int BaseCrossSocket::writeLine(string message, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //TODO: Why cant we append the data?
 | 
				
			||||||
 | 
					    //int returnValue = send(_socketHandle, message.append("\r\n").data(), strlen(message.data()), 0);
 | 
				
			||||||
 | 
					    int returnValue = send(_socketHandle, message.data(), message.size(), 0);
 | 
				
			||||||
 | 
					    send(_socketHandle, "\r\n", 2, 0);
 | 
				
			||||||
 | 
					    return returnValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int BaseCrossSocket::writeLine(string message, size_t length, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{	
 | 
				
			||||||
 | 
					    int returnValue = send(_socketHandle, message.data(), length, 0);
 | 
				
			||||||
 | 
					    send(_socketHandle, "\r\n", 2, 0);
 | 
				
			||||||
 | 
					    return returnValue;     
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int BaseCrossSocket::write(const string message, size_t length, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{	
 | 
				
			||||||
 | 
					    return send(_socketHandle, message.data(), length, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int BaseCrossSocket::write(const string message, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{	
 | 
				
			||||||
 | 
					    return send(_socketHandle, message.data(), message.size(), 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::setPassword(const string password)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   _password = password;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t BaseCrossSocket::read(char *buffer, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssize_t returnValue = 0;
 | 
				
			||||||
 | 
					    char singleCharacter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::read() - No connection");
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!waitRead(error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    while (size_t i = recv(_socketHandle, buffer + returnValue, int(sizeof(buffer) - returnValue), 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (i == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        returnValue += i;
 | 
				
			||||||
 | 
					        if (returnValue > sizeof(buffer) -1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return returnValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t BaseCrossSocket::read(char *buffer, int bytes, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssize_t returnValue = 0;
 | 
				
			||||||
 | 
					    char singleCharacter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::read() - No connection");
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!waitRead(error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    while (size_t i = recv(_socketHandle, buffer + returnValue, int(bytes - returnValue), 0))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (i == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        returnValue += i;
 | 
				
			||||||
 | 
					        if (returnValue > bytes -1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return returnValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string BaseCrossSocket::readLine(int size, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char *buffer = new char[size];
 | 
				
			||||||
 | 
					    ssize_t returnValue = 0;
 | 
				
			||||||
 | 
					    char singleCharacter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::readLine() - No connection");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!waitRead(error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return string();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    while (size_t i = recv(_socketHandle, &singleCharacter, 1, 0))
 | 
				
			||||||
 | 
					    {  
 | 
				
			||||||
 | 
					        if (returnValue >= size || singleCharacter == '\n')
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (singleCharacter != '\r') 
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            buffer[returnValue++] = singleCharacter;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }    
 | 
				
			||||||
 | 
					    buffer[returnValue] = '\0';    
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (returnValue < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::readLine() error: ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (returnValue == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _closeSignal = true;  //we  received a close signal from client
 | 
				
			||||||
 | 
					        setError(error, terminated, "BaseCrossSocket::readLine() - Connection terminated by client");	
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return string(buffer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ssize_t BaseCrossSocket::readLine(char *buffer, int bytes, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ssize_t returnValue = 0;
 | 
				
			||||||
 | 
					    char singleCharacter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::readLine() - No connection");
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!waitRead(error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    while (size_t i = recv(_socketHandle, &singleCharacter, 1, 0))
 | 
				
			||||||
 | 
					    {  
 | 
				
			||||||
 | 
					        if (returnValue >= sizeof(buffer) || singleCharacter == '\n')
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (singleCharacter != '\r') 
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            buffer[returnValue++] = singleCharacter;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }  
 | 
				
			||||||
 | 
					    buffer[returnValue] = '\0';
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (returnValue < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::readLine() error: ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (returnValue == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _closeSignal = true;  //we  received a close signal from client
 | 
				
			||||||
 | 
					        setError(error, terminated, "BaseCrossSocket::readLine() - Connection terminated by client");	
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return returnValue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int BaseCrossSocket::getClientSocket(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_socketHandle > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					        return _socketHandle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setError(error, notConnected, "BaseCrossSocket::getClientSocket() - No descriptor");		
 | 
				
			||||||
 | 
					    return -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::getServerHost(sockaddr *host, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (host == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "BaseCrossSocket::getServerHost() - Got NULL pointer");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::getServerHost() - No socket");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sw_socklen_t temp = sizeof(sockaddr);
 | 
				
			||||||
 | 
					    if (getsockname(_socketHandle, host, &temp) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::getServerHost() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::setTimeout(unsigned int seconds, unsigned int miliSeconds)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _timeoutSeconds = seconds;
 | 
				
			||||||
 | 
					    _timeoutMicroSeconds = miliSeconds;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::getClientHost(sockaddr *client, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (client == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "BaseCrossSocket::getClientHost() - Got NULL pointer");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_socketHandle > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        sw_socklen_t temp = sizeof(sockaddr);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (getpeername(_socketHandle, client, &temp) != 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            handleError(error, "BaseCrossSocket::getClientHost() error: ");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, notConnected, "BaseCrossSocket::getClientHost() - No connection");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::reset()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _closeSignal = false;	
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::waitIO(ioTypeEnum &type, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_blockingMode != blocking)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Wait with select() even if no timeout is set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    timeval time; 
 | 
				
			||||||
 | 
					    timeval *timeForever = NULL;  // Forever waiting
 | 
				
			||||||
 | 
					    time.tv_sec = _timeoutSeconds;
 | 
				
			||||||
 | 
					    time.tv_usec = _timeoutMicroSeconds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (_timeoutSeconds > 0 || _timeoutMicroSeconds > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        timeForever = &time;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fd_set readFileDescriptorSet;
 | 
				
			||||||
 | 
					    fd_set writeFileDescriptorSet;
 | 
				
			||||||
 | 
					    fd_set exceptionFileDescriptorSet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    FD_ZERO     (&readFileDescriptorSet);
 | 
				
			||||||
 | 
					    FD_ZERO     (&writeFileDescriptorSet);
 | 
				
			||||||
 | 
					    FD_ZERO     (&exceptionFileDescriptorSet);
 | 
				
			||||||
 | 
					    FD_SET      (_socketHandle, &readFileDescriptorSet);
 | 
				
			||||||
 | 
					    FD_SET      (_socketHandle, &writeFileDescriptorSet);
 | 
				
			||||||
 | 
					    FD_SET      (_socketHandle, &exceptionFileDescriptorSet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int returnValue = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch (type)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case ioread:
 | 
				
			||||||
 | 
					            returnValue = select(_socketHandle+1, &readFileDescriptorSet, NULL, NULL, timeForever);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case iowrite:
 | 
				
			||||||
 | 
					            returnValue = select(_socketHandle+1, NULL, &writeFileDescriptorSet, NULL, timeForever);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ioexception:
 | 
				
			||||||
 | 
					            returnValue = select(_socketHandle+1, NULL, NULL, &exceptionFileDescriptorSet, timeForever);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ioreadWrite:
 | 
				
			||||||
 | 
					            returnValue = select(_socketHandle+1, &readFileDescriptorSet, &writeFileDescriptorSet, NULL, timeForever);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case ioall:
 | 
				
			||||||
 | 
					            returnValue = select(_socketHandle+1, &readFileDescriptorSet, &writeFileDescriptorSet, &exceptionFileDescriptorSet, timeForever);
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (returnValue == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, timeout, "BaseCrossSocket::waitIO() timeout");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    else if (returnValue < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "BaseCrossSocket::waitIO() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (FD_ISSET(_socketHandle, &readFileDescriptorSet))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					        type = ioread;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (FD_ISSET(_socketHandle, &writeFileDescriptorSet))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					        type = iowrite;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (FD_ISSET(_socketHandle, &exceptionFileDescriptorSet))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        noError(error);
 | 
				
			||||||
 | 
					        type = ioexception;
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setError(error, fatal, "BaseCrossSocket::waitIO() failed on select()");
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::waitRead(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ioTypeEnum temp = ioread;
 | 
				
			||||||
 | 
					    return waitIO(temp, error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BaseCrossSocket::waitWrite(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ioTypeEnum temp = iowrite;
 | 
				
			||||||
 | 
					    return waitIO(temp, error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string BaseCrossSocket::getError()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   return _error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::printError()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_error.size() > 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        fprintf(stderr, "CrossSocket error:\n%s!\n", _error.data());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::handleError(CrossSocketErrors *error, string message)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #ifdef __WIN32__
 | 
				
			||||||
 | 
					        // Winsock2 errorList (taken from winsock2.h)
 | 
				
			||||||
 | 
					        switch (WSAGetLastError())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            case 0:                   message += "No error"; break;
 | 
				
			||||||
 | 
					            case WSAEINTR:            message += "Interrupted system call"; break;
 | 
				
			||||||
 | 
					            case WSAEBADF:            message += "Bad file number"; break;
 | 
				
			||||||
 | 
					            case WSAEACCES:           message += "Permission denied"; break;
 | 
				
			||||||
 | 
					            case WSAEFAULT:           message += "Bad address"; break;
 | 
				
			||||||
 | 
					            case WSAEINVAL:           message += "Invalid argument"; break;
 | 
				
			||||||
 | 
					            case WSAEMFILE:           message += "Too many open sockets"; break;
 | 
				
			||||||
 | 
					            case WSAEWOULDBLOCK:      message += "Operation would block"; break;
 | 
				
			||||||
 | 
					            case WSAEINPROGRESS:      message += "Operation now in progress"; break;
 | 
				
			||||||
 | 
					            case WSAEALREADY:         message += "Operation already in progress"; break;
 | 
				
			||||||
 | 
					            case WSAENOTSOCK:         message += "Socket operation on non-socket"; break;
 | 
				
			||||||
 | 
					            case WSAEDESTADDRREQ:     message += "Destination address required"; break;
 | 
				
			||||||
 | 
					            case WSAEMSGSIZE:         message += "Message too long"; break;
 | 
				
			||||||
 | 
					            case WSAEPROTOTYPE:       message += "Protocol wrong type for socket"; break;
 | 
				
			||||||
 | 
					            case WSAENOPROTOOPT:      message += "Bad protocol option"; break;
 | 
				
			||||||
 | 
					            case WSAEPROTONOSUPPORT:  message += "Protocol not supported"; break;
 | 
				
			||||||
 | 
					            case WSAESOCKTNOSUPPORT:  message += "Socket type not supported"; break;
 | 
				
			||||||
 | 
					            case WSAEOPNOTSUPP:       message += "Operation not supported on socket"; break;
 | 
				
			||||||
 | 
					            case WSAEPFNOSUPPORT:     message += "Protocol family not supported"; break;
 | 
				
			||||||
 | 
					            case WSAEAFNOSUPPORT:     message += "Address family not supported"; break;
 | 
				
			||||||
 | 
					            case WSAEADDRINUSE:       message += "Address already in use"; break;
 | 
				
			||||||
 | 
					            case WSAEADDRNOTAVAIL:    message += "Can't assign requested address"; break;
 | 
				
			||||||
 | 
					            case WSAENETDOWN:         message += "Network is down"; break;
 | 
				
			||||||
 | 
					            case WSAENETUNREACH:      message += "Network is unreachable"; break;
 | 
				
			||||||
 | 
					            case WSAENETRESET:        message += "Net connection reset"; break;
 | 
				
			||||||
 | 
					            case WSAECONNABORTED:     message += "Software caused connection abort"; break;
 | 
				
			||||||
 | 
					            case WSAECONNRESET:       message += "Connection reset by client"; break;
 | 
				
			||||||
 | 
					            case WSAENOBUFS:          message += "No buffer space available"; break;
 | 
				
			||||||
 | 
					            case WSAEISCONN:          message += "Socket is already connected"; break;
 | 
				
			||||||
 | 
					            case WSAENOTCONN:         message += "Socket is not connected"; break;
 | 
				
			||||||
 | 
					            case WSAESHUTDOWN:        message += "Can't send after socket shutdown"; break;
 | 
				
			||||||
 | 
					            case WSAETOOMANYREFS:     message += "Too many references"; break;
 | 
				
			||||||
 | 
					            case WSAETIMEDOUT:        message += "Connection timed out"; break;
 | 
				
			||||||
 | 
					            case WSAECONNREFUSED:     message += "Connection refused"; break;
 | 
				
			||||||
 | 
					            case WSAELOOP:            message += "Too many levels of symbolic links"; break;
 | 
				
			||||||
 | 
					            case WSAENAMETOOLONG:     message += "File name too long"; break;
 | 
				
			||||||
 | 
					            case WSAEHOSTDOWN:        message += "Host is down"; break;
 | 
				
			||||||
 | 
					            case WSAEHOSTUNREACH:     message += "No route to host"; break;
 | 
				
			||||||
 | 
					            case WSAENOTEMPTY:        message += "Directory not empty"; break;
 | 
				
			||||||
 | 
					            case WSAEPROCLIM:         message += "Too many processes"; break;
 | 
				
			||||||
 | 
					            case WSAEUSERS:           message += "Too many users"; break;
 | 
				
			||||||
 | 
					            case WSAEDQUOT:           message += "Disc quota exceeded"; break;
 | 
				
			||||||
 | 
					            case WSAESTALE:           message += "Stale NFS file handle"; break;
 | 
				
			||||||
 | 
					            case WSAEREMOTE:          message += "Too many levels of remote in path"; break;
 | 
				
			||||||
 | 
					            case WSASYSNOTREADY:      message += "Network system is unavailable"; break;
 | 
				
			||||||
 | 
					            case WSAVERNOTSUPPORTED:  message += "Winsock version out of range"; break;
 | 
				
			||||||
 | 
					            case WSANOTINITIALISED:   message += "WSAStartup not yet called"; break;
 | 
				
			||||||
 | 
					            case WSAEDISCON:          message += "Graceful shutdown in progress"; break;
 | 
				
			||||||
 | 
					            case WSAHOST_NOT_FOUND:   message += "Host not found"; break;
 | 
				
			||||||
 | 
					            case WSANO_DATA:          message += "No host data of that type was found"; break;
 | 
				
			||||||
 | 
					            default:                  message += "Unknown Winsock error: " + WSAGetLastError(); break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    #else
 | 
				
			||||||
 | 
					        message += strerror(errno);
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					    int errorNumber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #ifdef __WIN32__
 | 
				
			||||||
 | 
					      errorNumber = WSAGetLastError();
 | 
				
			||||||
 | 
					    #else
 | 
				
			||||||
 | 
					      errorNumber = errno;
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CrossSocketErrorsEnum errorMessage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (errorNumber == EADDRINUSE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = portInUse;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == EAGAIN || errorNumber == EWOULDBLOCK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = notReady;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == EMSGSIZE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = messageTooLong;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == EINPROGRESS || errorNumber == EALREADY)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = notReady;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == ECONNREFUSED || errorNumber == ETIMEDOUT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = noResponse;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == ENOTCONN || errorNumber == EBADF || errorNumber == ENOTSOCK)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = notConnected;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == EPIPE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = terminated;
 | 
				
			||||||
 | 
					        _closeSignal = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (errorNumber == EINTR)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = interrupted;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        errorMessage = fatal; //default
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setError(error, errorMessage, message);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::noError(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (error != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *error = ok;
 | 
				
			||||||
 | 
					        error->_error = "";
 | 
				
			||||||
 | 
					        error->failed_class = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BaseCrossSocket::setError(CrossSocketErrors *error, CrossSocketErrors name, string message)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _error = message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (error != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *error = name;
 | 
				
			||||||
 | 
					        error->_error = message;
 | 
				
			||||||
 | 
					        error->failed_class = this;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (ERRORMODE == 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            printError();
 | 
				
			||||||
 | 
					            if (name == terminated)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                disconnect();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (ERRORMODE == 1)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Reset the state
 | 
				
			||||||
 | 
					            reset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            close(_socketHandle);
 | 
				
			||||||
 | 
					            _socketHandle = -1;            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            CrossSocketErrors crossSocketError;
 | 
				
			||||||
 | 
					            crossSocketError = name;
 | 
				
			||||||
 | 
					            crossSocketError._error = message;
 | 
				
			||||||
 | 
					            crossSocketError.failed_class = this;
 | 
				
			||||||
 | 
					            throw crossSocketError;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            exit(-1);	
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										107
									
								
								BaseCrossSocket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								BaseCrossSocket.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// BaseCrossSocket.h
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossSocketsCore.h"
 | 
				
			||||||
 | 
					#include "CrossSocketConfig.h"
 | 
				
			||||||
 | 
					#include "CrossSocketErrors.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossThreadsHandler;
 | 
				
			||||||
 | 
					class CrossSocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseCrossSocket
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:	
 | 
				
			||||||
 | 
						BaseCrossSocket();
 | 
				
			||||||
 | 
						virtual ~BaseCrossSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Blocking     :       Everything blocks until operation is done
 | 
				
			||||||
 | 
					        // noWait       :       First call time blocking only
 | 
				
			||||||
 | 
					        // nonBlocking  :       Allow everything simultaneously
 | 
				
			||||||
 | 
						enum blockTypeEnum
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            blocking, 
 | 
				
			||||||
 | 
					            noWait, 
 | 
				
			||||||
 | 
					            nonblocking
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					        // wait for I/O (with timeout)
 | 
				
			||||||
 | 
						enum ioTypeEnum
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            ioread, 
 | 
				
			||||||
 | 
					            iowrite, 
 | 
				
			||||||
 | 
					            ioexception, 
 | 
				
			||||||
 | 
					            ioreadWrite, 
 | 
				
			||||||
 | 
					            ioall
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						virtual bool listen(int connectionLimit = 5, CrossSocketErrors* = NULL);
 | 
				
			||||||
 | 
						virtual BaseCrossSocket* accept(CrossSocketErrors* = NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					        virtual bool isConnected();
 | 
				
			||||||
 | 
						virtual bool disconnect(CrossSocketErrors* = NULL);
 | 
				
			||||||
 | 
					        virtual bool checkPassword(BaseCrossSocket *socket);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// force to close the socket
 | 
				
			||||||
 | 
						virtual bool closeSocketHandle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        virtual int write(const std::string message, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual int write(const std::string message, size_t length, CrossSocketErrors *error = NULL);        
 | 
				
			||||||
 | 
						virtual int writeLine(std::string message, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual int writeLine(std::string message, size_t length, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual ssize_t read(char *buffer, int bytes, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual ssize_t read(char *buffer, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual ssize_t readLine(char *buffer, int bytes, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual std::string readLine(int size, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
					        virtual void setPassword(const std::string password);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						virtual int getClientSocket(CrossSocketErrors *error);
 | 
				
			||||||
 | 
						virtual bool getServerHost(sockaddr *host, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual bool getClientHost(sockaddr *client, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					        // Receive timeout (can only be used in blocking mode)
 | 
				
			||||||
 | 
						void setTimeout(unsigned int seconds, unsigned int miliseconds);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// Error handling
 | 
				
			||||||
 | 
						virtual void printError();
 | 
				
			||||||
 | 
						virtual std::string getError();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						virtual void getSocket() = 0;
 | 
				
			||||||
 | 
						virtual BaseCrossSocket* create(int socketdescriptor, CrossSocketErrors *error) = 0;
 | 
				
			||||||
 | 
						virtual void reset();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						virtual bool waitIO(ioTypeEnum &type, CrossSocketErrors *error);
 | 
				
			||||||
 | 
						bool waitRead(CrossSocketErrors *error);
 | 
				
			||||||
 | 
						bool waitWrite(CrossSocketErrors *error);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						virtual void handleError(CrossSocketErrors *error, std::string message);
 | 
				
			||||||
 | 
						virtual void noError(CrossSocketErrors *error);
 | 
				
			||||||
 | 
						virtual void setError(CrossSocketErrors *error, CrossSocketErrors name, std::string message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int _socketHandle;
 | 
				
			||||||
 | 
					        std::string _password;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        BaseCrossSocket *_clientSocket;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// last error
 | 
				
			||||||
 | 
						std::string _error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// have we received a shutdown signal?
 | 
				
			||||||
 | 
						bool _closeSignal;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// blocking mode
 | 
				
			||||||
 | 
						blockTypeEnum _blockingMode;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        CrossThreadsHandler     *_threadHandler;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
						// timeout for waitIO()
 | 
				
			||||||
 | 
						int _timeoutSeconds;
 | 
				
			||||||
 | 
						int _timeoutMicroSeconds;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										252
									
								
								CrossSocket.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								CrossSocket.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,252 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocket.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossSocket.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __WIN32__
 | 
				
			||||||
 | 
					  #include <netdb.h>
 | 
				
			||||||
 | 
					  #include <arpa/inet.h>
 | 
				
			||||||
 | 
					  #include <fcntl.h>
 | 
				
			||||||
 | 
					  #include <sys/select.h>
 | 
				
			||||||
 | 
					  #include <sys/time.h>
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  #define F_SETFL FIONBIO
 | 
				
			||||||
 | 
					  #define O_NONBLOCK 1
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  extern int close(int fd);
 | 
				
			||||||
 | 
					  extern int fcntl(int fd, int cmd, long arg);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossSocket::CrossSocket(blockTypeEnum block)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _blockingMode = block;    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossSocket::~CrossSocket()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossSocket::getSocket()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_socketHandle < 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _socketHandle = socket(PF_INET, SOCK_STREAM, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (_blockingMode == nonblocking)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            fcntl(_socketHandle, F_SETFL, O_NONBLOCK);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //reset state	
 | 
				
			||||||
 | 
					        reset();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BaseCrossSocket* CrossSocket::create(int socketdescriptor, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CrossSocket* remoteClass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    remoteClass = new CrossSocket(_blockingMode);
 | 
				
			||||||
 | 
					    remoteClass->_socketHandle = socketdescriptor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return remoteClass;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossSocket::bind(int port, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return bind(port, "", error);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossSocket::bind(int port, string host, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    hostent *hostEntry;
 | 
				
			||||||
 | 
					    in_addr networkAddress; 	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (host.size() > 0 )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Bind to a specific address
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((hostEntry = gethostbyname(host.data())) == NULL)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            setError(error, fatal, "CrossSocket::bind() - Can't get host by name");
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        networkAddress = *((in_addr *)hostEntry->h_addr);
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					     else
 | 
				
			||||||
 | 
					     {
 | 
				
			||||||
 | 
					        // Bind to any address
 | 
				
			||||||
 | 
					        networkAddress.s_addr = INADDR_ANY;
 | 
				
			||||||
 | 
					     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sockaddr_in serverAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(&serverAddress, 0, sizeof(serverAddress));
 | 
				
			||||||
 | 
					    serverAddress.sin_family = AF_INET;
 | 
				
			||||||
 | 
					    serverAddress.sin_port = htons(port);
 | 
				
			||||||
 | 
					    serverAddress.sin_addr.s_addr = networkAddress.s_addr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (::bind(_socketHandle, (sockaddr *)&serverAddress, sizeof(serverAddress)) == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "CrossSocket::bind() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossSocket::connect(int port, string hostname, CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    getSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hostent *host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((host = gethostbyname(hostname.data())) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "CrossSocket::connect() - Can't get host by name");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sockaddr_in clientAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(&clientAddress, 0, sizeof(clientAddress));
 | 
				
			||||||
 | 
					    clientAddress.sin_family = AF_INET;
 | 
				
			||||||
 | 
					    clientAddress.sin_port = htons(port);
 | 
				
			||||||
 | 
					    clientAddress.sin_addr = *((in_addr *)host->h_addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (::connect(_socketHandle, (sockaddr *)&clientAddress, sizeof(clientAddress)) == -1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "CrossSocket::connect() error: ");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string CrossSocket::getClientAddress(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sockaddr_in clientAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!getClientHost((sockaddr *)&clientAddress, error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *addressPointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((addressPointer = inet_ntoa(clientAddress.sin_addr)) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "CrossSocket::getClientHostName() - Can't get client address");
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return string (addressPointer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int CrossSocket::getClientPort(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sockaddr_in clientAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!getClientHost((sockaddr *)&clientAddress, error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ntohs(clientAddress.sin_port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string CrossSocket::getClientHostName(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    string name = getClientAddress(error);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (name.size() < 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hostent *host; 	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((host = gethostbyname(name.data())) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "CrossSocket::getClientHostName() - Can't get client by address");
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return string(host->h_name);;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string CrossSocket::getServerAddress(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    //We need to get the real address, so we must
 | 
				
			||||||
 | 
					    //first get this computers host name and then
 | 
				
			||||||
 | 
					    //translate that into an address!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string name = getServerHostName(error);
 | 
				
			||||||
 | 
					    if (name.size() < 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hostent *host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((host = gethostbyname(name.data())) == NULL )
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "CrossSocket::getServerAddress() - Can't get host by name");
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char *addressPointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((addressPointer = inet_ntoa(*((in_addr *)host->h_addr))) == NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        setError(error, fatal, "CrossSocket::getServerAddress() - Can't get host address");
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return string(addressPointer);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int CrossSocket::getServerPort(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    sockaddr_in address;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!getServerHost((sockaddr *)&address, error))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return ntohs(address.sin_port);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string CrossSocket::getServerHostName(CrossSocketErrors *error)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char buffer[256];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (gethostname(buffer, 256) != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        handleError(error, "CrossSocket::gethostname() error: ");
 | 
				
			||||||
 | 
					        return "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    string message(buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    noError(error);
 | 
				
			||||||
 | 
					    return message;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								CrossSocket.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								CrossSocket.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocket.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossSocketsCore.h"
 | 
				
			||||||
 | 
					#include "BaseCrossSocket.h"
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossSocket : public BaseCrossSocket
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						CrossSocket(blockTypeEnum block = blocking);
 | 
				
			||||||
 | 
						virtual ~CrossSocket();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						virtual bool bind(int port, CrossSocketErrors *error = NULL);  //use port=0 to get any free port
 | 
				
			||||||
 | 
						virtual bool bind(int port, std::string host, CrossSocketErrors *error = NULL); //you can also specify the host interface to use
 | 
				
			||||||
 | 
						virtual bool connect(int port, std::string hostname, CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						// Tools
 | 
				
			||||||
 | 
						// Gets IP address, name or port.
 | 
				
			||||||
 | 
						virtual std::string getClientAddress(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual int getClientPort(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual std::string getClientHostName(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual std::string getServerAddress(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual int getServerPort(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						virtual std::string getServerHostName(CrossSocketErrors *error = NULL);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					protected:	
 | 
				
			||||||
 | 
						virtual void getSocket();
 | 
				
			||||||
 | 
						virtual BaseCrossSocket* create(int socketdescriptor, CrossSocketErrors *error);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										9
									
								
								CrossSocketConfig.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								CrossSocketConfig.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocketConfig.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set the errorMode (0: Verbose error  1: Throw error)
 | 
				
			||||||
 | 
					#define ERRORMODE 0
 | 
				
			||||||
							
								
								
									
										52
									
								
								CrossSocketErrors.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								CrossSocketErrors.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocketErrors.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BaseCrossSocket.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossSocketErrors::CrossSocketErrors()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    be = ok;
 | 
				
			||||||
 | 
					    _error = "";
 | 
				
			||||||
 | 
					    failed_class = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossSocketErrors::CrossSocketErrors(CrossSocketErrorsEnum e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    be = e;
 | 
				
			||||||
 | 
					    _error = "";
 | 
				
			||||||
 | 
					    failed_class = NULL;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					string CrossSocketErrors::getError()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _error;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BaseCrossSocket* CrossSocketErrors::getFailedClass(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return failed_class;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossSocketErrors::setErrorString(string msg)
 | 
				
			||||||
 | 
					{ 
 | 
				
			||||||
 | 
					    _error = msg;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossSocketErrors::setFailedClass(BaseCrossSocket *pnt)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    failed_class = pnt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossSocketErrors::operator==(CrossSocketErrors e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return be == e.be;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
					bool CrossSocketErrors::operator!=(CrossSocketErrors e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return be != e.be;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								CrossSocketErrors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								CrossSocketErrors.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocketErrors.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum CrossSocketErrorsEnum
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    ok,                 // Operation successful
 | 
				
			||||||
 | 
					    fatal,              // Unspecified error
 | 
				
			||||||
 | 
					    notReady,           // The socket was not ready (blockMode)
 | 
				
			||||||
 | 
					    portInUse,          // The specified port is already in use
 | 
				
			||||||
 | 
					    notConnected,       // The socket is invalid or not connected
 | 
				
			||||||
 | 
					    messageTooLong,     // The messageSize is too big to be send
 | 
				
			||||||
 | 
					    terminated,         // Connection terminated (by client)
 | 
				
			||||||
 | 
					    noResponse,         // Cannot connect to client
 | 
				
			||||||
 | 
					    timeout,            // Read/Write operation timeout occurred (in blockingMode)
 | 
				
			||||||
 | 
					    interrupted         // Operation was blocked by signal
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseCrossSocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossSocketErrors
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    CrossSocketErrors();
 | 
				
			||||||
 | 
					    CrossSocketErrors(CrossSocketErrorsEnum e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual ~CrossSocketErrors(){;}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual std::string getError();
 | 
				
			||||||
 | 
					    virtual BaseCrossSocket* getFailedClass(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual bool operator == (CrossSocketErrors e);
 | 
				
			||||||
 | 
					    virtual bool operator != (CrossSocketErrors e);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    virtual void setErrorString(std::string msg);
 | 
				
			||||||
 | 
					    virtual void setFailedClass(BaseCrossSocket *pnt);
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
					    friend class BaseCrossSocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The base error type
 | 
				
			||||||
 | 
					    CrossSocketErrorsEnum be;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Human readable error string
 | 
				
			||||||
 | 
					    std::string _error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // A pointer to the class causing the error
 | 
				
			||||||
 | 
					    BaseCrossSocket *failed_class;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										62
									
								
								CrossSocketPlatform.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								CrossSocketPlatform.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocketPlatform.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					// Define the errorCodes for the Windows platform (taken from CYGWIN error numbers)
 | 
				
			||||||
 | 
					  #define EOPNOTSUPP WSAEOPNOTSUPP
 | 
				
			||||||
 | 
					  #define EINTR WSAEINTR
 | 
				
			||||||
 | 
					  #define EADDRINUSE WSAEADDRINUSE
 | 
				
			||||||
 | 
					  #define EINPROGRESS WSAEINPROGRESS
 | 
				
			||||||
 | 
					  #define EWOULDBLOCK WSAEWOULDBLOCK
 | 
				
			||||||
 | 
					  #define ENOTSOCK WSAENOTSOCK
 | 
				
			||||||
 | 
					  #define EMSGSIZE WSAEMSGSIZE
 | 
				
			||||||
 | 
					  #define ETIMEDOUT WSAETIMEDOUT
 | 
				
			||||||
 | 
					  #define EALREADY WSAEALREADY
 | 
				
			||||||
 | 
					  #define EBADF WSAEBADF 
 | 
				
			||||||
 | 
					  #define ECONNREFUSED WSAECONNREFUSED
 | 
				
			||||||
 | 
					  #define ENOTCONN WSAENOTCONN
 | 
				
			||||||
 | 
					#else 
 | 
				
			||||||
 | 
					  #include <netdb.h>
 | 
				
			||||||
 | 
					  #include <arpa/inet.h>
 | 
				
			||||||
 | 
					  #include <fcntl.h>
 | 
				
			||||||
 | 
					  #include <sys/select.h>
 | 
				
			||||||
 | 
					  #include <sys/time.h>
 | 
				
			||||||
 | 
					  #include <sstream>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  #define SOCKETFAIL -1
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MSG_NOSIGNAL
 | 
				
			||||||
 | 
					#define MSG_NOSIGNAL 0
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Redefine the socklen_t parameter because it is different on Windows
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					  #define sw_socklen_t int
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  #define sw_socklen_t socklen_t
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int fcntl(int fd, int cmd, long arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    unsigned long mode = arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return WSAIoctl(fd, cmd, &mode, sizeof(unsigned long), NULL, 0, NULL, NULL, NULL);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int close(int fd)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return closesocket(fd);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WSA_exit(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    WSACleanup();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										9
									
								
								CrossSockets.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								CrossSockets.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSockets.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "BaseCrossSocket.h"
 | 
				
			||||||
 | 
					#include "CrossSocket.h"
 | 
				
			||||||
							
								
								
									
										18
									
								
								CrossSocketsCore.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								CrossSocketsCore.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					// CrossSockets
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 27-01-2013
 | 
				
			||||||
 | 
					// CrossSocketsCore.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					  #include <winsock2.h>
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  #define F_SETFL FIONBIO
 | 
				
			||||||
 | 
					  #define O_NONBLOCK 1
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  #include <sys/types.h> 
 | 
				
			||||||
 | 
					  #include <sys/socket.h> 
 | 
				
			||||||
 | 
					  #include <netinet/in.h>
 | 
				
			||||||
 | 
					  #include <sys/un.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								CrossSockets_protocol.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								CrossSockets_protocol.pdf
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										109
									
								
								CrossThreads.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								CrossThreads.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,109 @@
 | 
				
			|||||||
 | 
					// CrossThreads
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 29-01-2013
 | 
				
			||||||
 | 
					// CrossThread.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossThreads.h"
 | 
				
			||||||
 | 
					#include "errno.h"
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossThreads::CrossThreads(threadCallBack callBack, long timeout) : _callBack(callBack), _threadID(0)
 | 
				
			||||||
 | 
					#ifdef __WIN32__ 
 | 
				
			||||||
 | 
					, _timeout(timeout) , _thread(NULL) 
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossThreads::~CrossThreads()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    stop();	
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossThreads::stop()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    #ifdef __WIN32__
 | 
				
			||||||
 | 
					        //waiting for the thread to terminate
 | 
				
			||||||
 | 
					        if (_thread) 
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (WAIT_TIMEOUT == ::WaitForSingleObject (_thread, _timeout))
 | 
				
			||||||
 | 
					                    ::TerminateThread (_thread, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ::CloseHandle (_thread);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int CrossThreads::create()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					#ifdef __WIN32__
 | 
				
			||||||
 | 
					    _thread = ::CreateThread (NULL, 0, 
 | 
				
			||||||
 | 
					            (unsigned long (__stdcall *)(void *))_callBack, 
 | 
				
			||||||
 | 
					            NULL, 0, &_thread);
 | 
				
			||||||
 | 
					    if (NULL == _thread)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        break;	
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					    pthread_attr_t attribute;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize and set thread and set the attribute
 | 
				
			||||||
 | 
					    pthread_attr_init(&attribute);
 | 
				
			||||||
 | 
					    pthread_attr_setdetachstate(&attribute, PTHREAD_CREATE_DETACHED);				
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    int result;
 | 
				
			||||||
 | 
					    do 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        result = pthread_create(&_threadID, &attribute, _callBack, (void *)this);
 | 
				
			||||||
 | 
					    } while (false);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (result != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << "CrossThread: Failed to create the thread\n";
 | 
				
			||||||
 | 
					        if (result == EAGAIN)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::cout << "The system lacked the necessary resource to create another thread";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (result == EINVAL)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::cout << "CrossThread: The value given in the arguments is invalid!";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            std::cout << "CrossThread: The caller does not have the appropriate rights";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Free the attributes of the thread
 | 
				
			||||||
 | 
					    pthread_attr_destroy(&attribute);
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossThreads::join()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (0 != pthread_join(_threadID, NULL)) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					       fprintf(stderr, "pthread_join error\n");
 | 
				
			||||||
 | 
					    }   
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int CrossThreads::remove()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return pthread_detach(_threadID);
 | 
				
			||||||
 | 
					} 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long CrossThreads::getThreadID()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return printf("%lu\n", (unsigned long) _threadID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void CrossThreads::setThreadCallback(threadCallBack callBack)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _callBack = callBack;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossThreads::isCreated()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return _threadID ? true : false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										47
									
								
								CrossThreads.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								CrossThreads.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					// CrossThreads
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 29-01-2013
 | 
				
			||||||
 | 
					// CrossThreads.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __WIN32__
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					#include "pthread.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef pthread_t threadID;
 | 
				
			||||||
 | 
					typedef void* (*threadCallBack)(void* parameter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <windows.h>
 | 
				
			||||||
 | 
					typedef unsigned long (*threadCallBack)(void* parameter);
 | 
				
			||||||
 | 
					typedef DWORD threadID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossThreads
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        CrossThreads(threadCallBack callBack = NULL, long timeout = 3000);
 | 
				
			||||||
 | 
					        virtual ~CrossThreads();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void setThreadCallback(threadCallBack callBack); 
 | 
				
			||||||
 | 
					        unsigned long getThreadID();
 | 
				
			||||||
 | 
					        int create();
 | 
				
			||||||
 | 
					        int remove();
 | 
				
			||||||
 | 
					        void join();
 | 
				
			||||||
 | 
					        bool isCreated();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        threadID		_threadID;
 | 
				
			||||||
 | 
					        threadCallBack		_callBack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #ifdef __WIN32__
 | 
				
			||||||
 | 
					            long			_timeout;
 | 
				
			||||||
 | 
					            HANDLE			_thread;
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        void stop();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										58
									
								
								CrossThreadsHandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								CrossThreadsHandler.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					// CrossThreadsHandler
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 29-01-2013
 | 
				
			||||||
 | 
					// CrossThreadsHandler.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossThreadsHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossThreadsHandler::CrossThreadsHandler() 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long CrossThreadsHandler::createAndStartThread(threadCallBack callback)
 | 
				
			||||||
 | 
					{        
 | 
				
			||||||
 | 
					    CrossThreads *thread = new CrossThreads(callback);
 | 
				
			||||||
 | 
					    thread->create();
 | 
				
			||||||
 | 
					    _threadList.insert(pair<unsigned long, CrossThreads*>(thread->getThreadID(),thread));
 | 
				
			||||||
 | 
					    return thread->getThreadID();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossThreadsHandler::joinThread(unsigned long threadID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					   map <unsigned long, CrossThreads*>::iterator iterator = _threadList.find(threadID);
 | 
				
			||||||
 | 
					    if (iterator != _threadList.end())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        iterator->second->join();
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cout << "The client could not be found in the threadList.";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool CrossThreadsHandler::removeThread(unsigned long threadID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    map <unsigned long, CrossThreads*>::iterator iterator = _threadList.find(threadID);
 | 
				
			||||||
 | 
					    if (iterator != _threadList.end())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _threadList.erase(iterator);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        cout << "The client could not be found in the threadList.";
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CrossThreadsHandler::~CrossThreadsHandler() 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								CrossThreadsHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								CrossThreadsHandler.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					// CrossThreadsHandler
 | 
				
			||||||
 | 
					// Copyright Jeroen Saey
 | 
				
			||||||
 | 
					// Created 29-01-2013
 | 
				
			||||||
 | 
					// CrossThreadsHandler.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossThreads.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossThreadsHandler 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        CrossThreadsHandler();
 | 
				
			||||||
 | 
					        virtual ~CrossThreadsHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        unsigned long         createAndStartThread      (threadCallBack callback);
 | 
				
			||||||
 | 
					        bool                  removeThread              (unsigned long threadID);
 | 
				
			||||||
 | 
					        bool                  joinThread                (unsigned long threadID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        std::map<unsigned long, CrossThreads*>          _threadList;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										66
									
								
								Example/server.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Example/server.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * File:   Server.cpp
 | 
				
			||||||
 | 
					 * Author: SuperSmash
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Created on 15 february 2013, 21:10
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Server.h"
 | 
				
			||||||
 | 
					#include "CrossSockets/CrossThreadsHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sstream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace std;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Server *self;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Server::Server() 
 | 
				
			||||||
 | 
					{       
 | 
				
			||||||
 | 
					    self = this;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Setup the listener into listeningMode and define the serverport
 | 
				
			||||||
 | 
					    _server.bind(2013);
 | 
				
			||||||
 | 
					    _server.listen();
 | 
				
			||||||
 | 
					    _server.setPassword("welcome");
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    stringstream startMessage;
 | 
				
			||||||
 | 
					    LogManagement::getInstance()->write(startMessage << "CrossSocket server started.\n" << "PORT: 2013");
 | 
				
			||||||
 | 
					    cout << APPLICATIONNAME << " server started.\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _threadHandler = new CrossThreadsHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while (_server.isConnected())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        listenForConnections((CrossSocket*)_server.accept());        
 | 
				
			||||||
 | 
					    }    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Server::listenForConnections(CrossSocket* socket)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _clientSocket = socket;
 | 
				
			||||||
 | 
					    stringstream welcomeMessage;
 | 
				
			||||||
 | 
					    welcomeMessage << "Welcome to the CrossSocket server!";
 | 
				
			||||||
 | 
					    socket->writeLine(welcomeMessage.str());
 | 
				
			||||||
 | 
					    _threadID = _threadHandler->createAndStartThread((threadCallBack) &Server::handleLoopCallback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void* Server::handleLoopCallback(void *functionPointer)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static_cast <Server*>(functionPointer)->handleLoop(self->_clientSocket, self->_threadID);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Server::handleLoop(CrossSocket *socket, unsigned long threadID)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (self->_server.checkPassword(socket))
 | 
				
			||||||
 | 
					    {    
 | 
				
			||||||
 | 
					        while (socket->isConnected())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            // Do something here because we got an active connection to the server using CrossSockets ^^
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        delete socket;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Server::~Server() 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										33
									
								
								Example/server.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Example/server.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					/* 
 | 
				
			||||||
 | 
					 * File:   Server.h
 | 
				
			||||||
 | 
					 * Author: SuperSmash
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Created on 15 february 2013, 21:10
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "CrossSockets/CrossSockets.h"
 | 
				
			||||||
 | 
					#include "CrossSockets/CrossThreads.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CrossThreadsHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Server 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public:
 | 
				
			||||||
 | 
					        Server();
 | 
				
			||||||
 | 
					        virtual ~Server();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        void listenForConnections(CrossSocket* socket);
 | 
				
			||||||
 | 
					        void deleteClientSocketWithForce(int signalnumber);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    private:
 | 
				
			||||||
 | 
					        static void* handleLoopCallback(void *functionPointer);
 | 
				
			||||||
 | 
					        void handleLoop(CrossSocket *socket, unsigned long threadID);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        CrossSocket             _server;
 | 
				
			||||||
 | 
					        CrossThreadsHandler     *_threadHandler;    
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        CrossSocket *_clientSocket;
 | 
				
			||||||
 | 
					        unsigned long _threadID;       
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
								
							@@ -1,3 +1,13 @@
 | 
				
			|||||||
# CrossSockets
 | 
					CrossSockets:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CrossSockets C++
 | 
					CrossSockets is a library for C++ to work with the POSIX and Winsock2 sockets.
 | 
				
			||||||
 | 
					CrossSockets can help you implement a network communication application.
 | 
				
			||||||
 | 
					CrossSockets was created to serve as a client - server communication protocol.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Example: 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If the server is running you can establish a connection using putty or any other client.
 | 
				
			||||||
 | 
					(if you use putty you need to connect to the server using a RAW connection)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Port: 2013
 | 
				
			||||||
 | 
					Password: welcome
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user