#pragma once
#include <config.h>
#ifdef SHAWN
#include <shawn_config.h>
#include "_apps_enable_cmake.h"
#ifdef ENABLE_TCPIP
#define BUILD_TCPIP
#endif
#else
#define BUILD_TCPIP
#endif
#ifdef BUILD_TCPIP
#ifdef SHAWN
#include <apps/tcpip/storage.h>
#else
#include "storage.h"
#endif
#ifdef SHAWN
namespace shawn
{ class SimulationController; }
extern "C" void init_tcpip( shawn::SimulationController& );
#endif
#include <string>
#include <map>
#include <vector>
#include <list>
#include <deque>
#include <iostream>
#include <cstddef>
struct sockaddr_in;
namespace tcpip
{
class SocketException: public std::runtime_error
{
public:
SocketException(std::string what) : std::runtime_error(what.c_str()) {}
};
class Socket
{
friend class Response;
public:
Socket(std::string host, int port);
Socket(int port);
~Socket();
static int getFreeSocketPort();
void connect();
Socket* accept(const bool create = false);
void send( const std::vector<unsigned char> &buffer);
void sendExact( const Storage & );
std::vector<unsigned char> receive( int bufSize = 2048 );
bool receiveExact( Storage &);
void close();
int port();
void set_blocking(bool);
bool is_blocking();
bool has_client_connection() const;
bool verbose() { return verbose_; }
void set_verbose(bool newVerbose) { verbose_ = newVerbose; }
protected:
static const int lengthLen;
void receiveComplete(unsigned char * const buffer, std::size_t len) const;
size_t recvAndCheck(unsigned char * const buffer, std::size_t len) const;
void printBufferOnVerbose(const std::vector<unsigned char> buffer, const std::string &label) const;
private:
void init();
static void BailOnSocketError(std::string context);
#ifdef WIN32
static std::string GetWinsockErrorString(int err);
#endif
bool datawaiting(int sock) const;
std::string host_;
int port_;
int socket_;
int server_socket_;
bool blocking_;
bool verbose_;
#ifdef WIN32
static bool init_windows_sockets_;
static bool windows_sockets_initialized_;
static int instance_count_;
#endif
};
}
#endif