Blame tcp.h

91ef56
#ifndef TCP_H
91ef56
#define TCP_H
91ef56
91ef56
91ef56
#include <atomic></atomic>
91ef56
#include <thread></thread>
91ef56
#include <vector></vector>
0ea18d
#include <list></list>
0ea18d
#include <mutex></mutex>
91ef56
91ef56
#include "error.h"
91ef56
91ef56
91ef56
enum : ErrorCode {
91ef56
	ERR_TCP_COMMON = ERR_TCP,
91ef56
	ERR_TCP_RESOLVE_FAILED,
91ef56
	ERR_TCP_BAD_ADDRESS,
91ef56
	ERR_TCP_BAD_HANDLER,
91ef56
	ERR_TCP_CONNECTION_FAILED,
91ef56
	ERR_TCP_CONNECTION_LOST,
91ef56
	ERR_TCP_LISTEN_FAILED,
91ef56
	ERR_TCP_LISTEN_LOST,
91ef56
};
91ef56
91ef56
91ef56
namespace Tcp {
91ef56
91ef56
enum Status {
91ef56
	STATUS_NONE,
91ef56
	STATUS_OPEN,
91ef56
	STATUS_CLOSED,
91ef56
	STATUS_LOST,
91ef56
};
91ef56
91ef56
91ef56
typedef int SockId;
91ef56
91ef56
91ef56
class Address {
91ef56
public:
91ef56
	unsigned char ip[4];
91ef56
	unsigned short port;
91ef56
	
91ef56
	inline Address():
91ef56
		ip(), port() { }
91ef56
	inline Address(unsigned char ip0, unsigned char ip1, unsigned char ip2, unsigned char ip3, unsigned short port):
91ef56
		port(port) { ip[0] = ip0, ip[1] = ip1, ip[2] = ip2, ip[3] = ip3; }
91ef56
	inline Address(unsigned char *ip, unsigned short port):
91ef56
		Address(ip[0], ip[1], ip[2], ip[3], port) { }
91ef56
	
91ef56
	inline bool isValidIp() const
91ef56
		{ return ip[0] || ip[1] || ip[2] || ip[3]; }
91ef56
	inline bool isValidPort() const
91ef56
		{ return port; }
91ef56
	inline bool isValid() const
91ef56
		{ return isValidIp() && isValidPort(); }
91ef56
		
91ef56
	ErrorCode resolve(const char *addrString);
91ef56
};
91ef56
91ef56
91ef56
class Connection {
91ef56
private:
91ef56
	Status status;
91ef56
	ErrorCode lastError;
91ef56
	SockId sockId;
91ef56
	Address remoteAddr;
91ef56
	std::atomic<bool> stopping;</bool>
91ef56
	
91ef56
	Connection(const Connection&) = delete;
91ef56
	Connection& operator=(const Connection&) = delete;
91ef56
91ef56
public:
91ef56
	Connection();
91ef56
	Connection(SockId sockId, const Address &remoteAddr);
91ef56
	~Connection();
91ef56
	
91ef56
	inline Status getStatus() const
91ef56
		{ return status; }
91ef56
	ErrorCode getLastError() const
91ef56
		{ return lastError; }
91ef56
	inline SockId getSockId() const
91ef56
		{ return sockId; }
91ef56
	inline const Address& getRemoteAddr() const
91ef56
		{ return remoteAddr; }
91ef56
	
91ef56
	inline void stop()
91ef56
		{ stopping = true; }
91ef56
	inline bool check() {
91ef56
		if (stopping) close(ERR_TCP_CONNECTION_LOST);
91ef56
		return status == STATUS_OPEN;
91ef56
	}
91ef56
	
91ef56
	bool open(const Address &remoteAddr);
91ef56
	void close(ErrorCode errorCode = ERR_NONE);
91ef56
	
91ef56
	bool read(void *data, size_t size);
91ef56
	bool write(const void *data, size_t size);
91ef56
};
91ef56
91ef56
91ef56
class Handler {
91ef56
public:
91ef56
	virtual ~Handler();
91ef56
	virtual void handleTcpConnection(Connection &connection) = 0;
91ef56
};
91ef56
91ef56
91ef56
class Server {
91ef56
public:
91ef56
	struct ConnDesc {
91ef56
		Connection *connection;
91ef56
		std::thread *thread;
91ef56
	};
0ea18d
	typedef std::list<conndesc> ConnList;</conndesc>
0ea18d
	typedef std::vector<conndesc> ConnVector;</conndesc>
91ef56
	
91ef56
private:
91ef56
	Status status;
91ef56
	ErrorCode lastError;
91ef56
	SockId sockId;
91ef56
	Address localAddr;
91ef56
	Handler *handler;
91ef56
	std::thread *thread;
91ef56
	std::atomic<bool> stopping;</bool>
91ef56
	
0ea18d
	std::mutex connectionsMutex;
0ea18d
	ConnList connections;
0ea18d
	ConnVector connectionsFinished;
0ea18d
	
91ef56
	Server(const Server&) = delete;
91ef56
	Server& operator=(const Server&) = delete;
91ef56
	
0ea18d
	void cleanConnections();
0ea18d
	void handleConnection(ConnList::iterator iter);
91ef56
	void listen();
91ef56
	
91ef56
public:
91ef56
	Server();
91ef56
	~Server();
91ef56
	
91ef56
	inline Status getStatus() const
91ef56
		{ return status; }
91ef56
	ErrorCode getLastError() const
91ef56
		{ return lastError; }
91ef56
	inline SockId getSockId() const
91ef56
		{ return sockId; }
91ef56
	inline const Address& getLocalAddr() const
91ef56
		{ return localAddr; }
91ef56
	inline Handler* getHandler() const
91ef56
		{ return handler; }
91ef56
	
91ef56
	inline bool check()
91ef56
		{ return !stopping && status == STATUS_OPEN; }
91ef56
91ef56
	bool start(const Address &localAddr, Handler *handler);
91ef56
	void join();
91ef56
	void stop();
91ef56
};
91ef56
91ef56
} // Tcp
91ef56
91ef56
#endif