Просмотр исходного кода

TCPSocket & UDPSocket implemented to os

mikymod 13 лет назад
Родитель
Сommit
14b53ef159

+ 2 - 0
src/CMakeLists.txt

@@ -225,6 +225,8 @@ set (LINUX_SRC
 	os/linux/LinuxOS.cpp
 	os/linux/LinuxTimer.cpp
 	os/linux/Input.cpp
+	os/linux/TCPSocket.cpp
+	os/linux/UDPSocket.cpp	
 )
 
 set (LINUX_HEADERS

+ 4 - 4
src/core/math/Angles.h

@@ -48,12 +48,12 @@ public:
 
 	real					heading, pitch, bank;
 
-							Angles();						//!< Constructor, does nothing for efficiency
-							~Angles();						//!< Destructor
-							Angles(real h, real p, real b);	//!< Construct from three values
+							Angles();							//!< Constructor, does nothing for efficiency
+							~Angles();							//!< Destructor
+							Angles(real h, real p, real b);		//!< Construct from three values
 
 
-	Str						to_str() const;					//!< Returns a Str containing the angles' components
+	Str						to_str() const;						//!< Returns a Str containing the angles' components
 	Mat3					to_mat3() const;					//!< Returns an equivalent Mat3 representation.
 	Mat4					to_mat4() const;					//!< Returns an equivalent Mat4 representation.
 	Quat					to_quat() const;					//!< Returns an equivalent Quat representation.

BIN
src/network/.TCPSocket.cpp.kate-swp


+ 153 - 0
src/network/AsyncServer.cpp

@@ -0,0 +1,153 @@
+
+namespace crown
+{
+	AsyncServer::AsyncServer()
+	{
+	  
+	}
+
+	AsyncServer::~AsyncServer()
+	{
+	  
+	}
+
+	bool AsyncServer::init_port()
+	{
+	  
+	}
+
+	void AsyncServer::close_port()
+	{
+	  
+	}
+			
+	int	AsyncServer::get_port() const
+	{
+	  
+	}
+
+	IPv4Address AsyncServer::get_bound_address() const
+	{
+	  
+	}
+
+	bool AsyncServer::is_active() const
+	{
+	  
+	}
+
+	int	AsyncServer::get_delay() const
+	{
+	  
+	}
+
+	int	AsyncServer::get_outgoing_rate() const
+	{
+	  
+	}
+
+	int	get_incoming_rate() const
+	{
+	
+	}
+
+	bool is_client_in_game(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_ping(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_prediction(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_time_since_last_packet(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_time_since_last_input(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_outgoing_rate(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_client_incoming_rate(int client_num) const
+	{
+	  
+	}
+
+	float AsyncServer::get_client_outgoing_compression(int client_num) const
+	{
+	  
+	}
+
+	float AsyncServer::get_client_incoming_compression(int client_num) const
+	{
+	  
+	}
+
+	float AsyncServer::get_client_incoming_packet_loss(int client_num) const
+	{
+	  
+	}
+
+	int	AsyncServer::get_num_clients() const
+	{
+	  
+	}
+
+	int	AsyncServer::get_num_idle_clients() const
+	{
+	  
+	}
+
+	int	AsyncServer::get_local_client_num() const 
+	{
+	  
+	}
+			
+	void AsyncServer::run_frame()
+	{
+	  
+	}
+
+	void AsyncServer::send_reliable_game_message(int clientNum, const idBitMsg &msg)
+	{
+	  
+	}
+
+	void AsyncServer::send_reliable_game_message_excluding(int clientNum, const idBitMsg &msg)
+	{
+	  
+	}
+
+	void AsyncServer::master_heartbeat( bool force = false )
+	{
+	  
+	}
+
+	void AsyncServer::drop_client( int clientNum, const char *reason )
+	{
+	  
+	}
+
+	void AsyncServer::update_async_stats_avg()
+	{
+	  
+	}
+
+	void AsyncServer::print_local_server_info()
+	{
+	}
+
+}

+ 189 - 0
src/network/AsyncServer.h

@@ -0,0 +1,189 @@
+#pragma once
+
+namespace crown
+{
+	// states for the server's authorization process
+	typedef enum 
+	{
+		AS_WAIT = 0,	// we are waiting for a confirm/deny from auth
+						// this is subject to timeout if we don't hear from auth
+						// or a permanent wait if auth said so
+		AS_OK,
+		AS_ONLYLAN,
+		AS_WAIT,
+		AS_OK,
+		AS_MAXSTATES
+	} 
+	authState;
+	
+//-------------------------------------------------------------------------------------
+
+	// states from the auth server, while the client is in CDK_WAIT
+	typedef enum 
+	{
+		AR_NONE = 0,	// no reply yet
+		AR_OK,			// this client is good
+		AR_WAIT,		// wait - keep sending me srvAuth though
+		AR_DENY,		// denied - don't send me anything about this client anymore
+		AR_MAXSTATES
+	} 
+	authReply;
+
+//-------------------------------------------------------------------------------------
+
+	// message from auth to be forwarded back to the client
+	// auth server has the possibility to send a custom reply
+	typedef enum 
+	{
+		ARM_WAITING = 0,	// waiting on an initial reply from auth
+		ARM_UNKNOWN,		// client unknown to auth
+		ARM_DENIED,			// access denied
+		ARM_PRINT,			// custom message
+		ARM_SRVWAIT,		// auth server replied and tells us he's working on it
+		ARM_MAXSTATES
+	} 
+	authReplyMsg;
+
+//-------------------------------------------------------------------------------------
+
+	typedef enum 
+	{
+	  SCS_FREE = 0,			// can be reused for a new connection
+	  SCS_ZOMBIE,			// client has been disconnected, but don't reuse connection for a couple seconds
+	  SCS_WAIT,				// client needs to update it's pure checksums before we can go further
+	  SCS_CONNECTED,		// client is connected
+	  SCS_INGAME			// client is in the game
+	} 
+	serverClientState;
+
+//-------------------------------------------------------------------------------------
+
+	typedef struct serverClient_s 
+	{
+		int					OS;
+		int					client_id;
+		serverClientState	client_state;
+		int					client_prediction;
+		int					client_ahead_time;
+		int					client_rate;
+		int					client_ping;
+
+		int					game_init_sequence;
+		int					game_frame;
+		int					game_time;
+
+// 		idMsgChannel		channel;
+		int					last_connect_time;
+		int					last_empty_time;
+		int					last_ping_time;
+		int					last_snapshot_time;
+		int					last_packet_time;
+		int					last_input_time;
+// 		int					snapshotSequence;
+// 		int					acknowledgeSnapshotSequence;
+// 		int					numDuplicatedUsercmds;
+
+// 		char				guid[12];  // Even Balance - M. Quinn
+
+	} 
+	serverClient;
+
+//-------------------------------------------------------------------------------------
+
+	class IPv4Address;
+
+//-------------------------------------------------------------------------------------
+
+	/**
+	 * Server arch over UDPSocket.
+	 */
+	class AsyncServer
+	{
+	public:
+							AsyncServer();
+							~AsyncServer();
+
+		bool				init_port();
+		void				close_port();
+		
+// 		void				Spawn();
+// 		void				Kill();
+// 		void				ExecuteMapChange();
+		
+		
+		int					get_port() const;
+		IPv4Address			get_bound_address() const;
+		bool				is_active() const;
+		int					get_delay() const;
+		int					get_outgoing_rate() const;
+		int					get_incoming_rate() const;
+		bool				is_client_in_game(int client_num) const;
+		int					get_client_ping(int client_num) const;
+		int					get_client_prediction(int client_num) const;
+		int					get_client_time_since_last_packet(int client_num) const;
+		int					get_client_time_since_last_input(int client_num) const;
+		int					get_client_outgoing_rate(int client_num) const;
+		int					get_client_incoming_rate(int client_num) const;
+		float				get_client_outgoing_compression(int client_num) const;
+		float				get_client_incoming_compression(int client_num) const;
+		float				get_client_incoming_packet_loss(int client_num) const;
+		int					get_num_clients() const;
+		int					get_num_idle_clients() const;
+		int					get_local_client_num() const 
+		
+ 		void				run_frame();
+// 		void				processConnectionLessMessages( void );
+// 		void				RemoteConsoleOutput( const char *string );
+		void				send_reliable_game_message(int clientNum, const idBitMsg &msg);
+		void				send_reliable_game_message_excluding(int clientNum, const idBitMsg &msg);
+// 		void				LocalClientSendReliableMessage( const idBitMsg &msg );
+
+		void				master_heartbeat( bool force = false );
+		void				drop_client( int clientNum, const char *reason );
+
+// 		void				PacifierUpdate( void );
+
+// 		void				UpdateUI( int clientNum );
+
+		void				update_async_stats_avg();
+// 		void				get_async_stats_avg_msg(idStr &msg);
+
+		void				print_local_server_info();
+		
+		const int 			MAX_ASYNC_CLIENTS = 30;	// tmp value
+		
+	private:
+
+		bool				active;						// true if server is active
+		int					real_time;					// absolute time
+
+		int					server_time;				// local server time
+		IPv4Address			server_addr;				// UDP port
+		int					server_id;					// server identification
+		int					server_data_checksum;		// checksum of the data used by the server
+		int					local_client_num;			// local client on listen server
+
+		serverClient		clients[MAX_ASYNC_CLIENTS];	// clients
+
+		int					game_init_id;				// game initialization identification
+		int					game_frame;					// local game frame
+		int					game_time;					// local game time
+		int					game_time_residual;			// left over time from previous frame
+	
+		int					next_heartbeat_time;
+		int					next_async_stats_time;
+
+		bool				noRconOutput;				// for default rcon response when command is silent
+
+		int					last_auth_time;				// global for auth server timeout
+
+		// track the max outgoing rate over the last few secs to watch for spikes
+		// dependent on net_serverSnapshotDelay. 50ms, for a 3 seconds backlog -> 60 samples
+		static const int	stats_numsamples = 60;
+		int					stats_outrate[ stats_numsamples ];
+		int					stats_current;
+		int					stats_average_sum;
+		int					stats_max;
+		int					stats_max_index;	  
+	};
+}

+ 95 - 0
src/network/IPv4Address.h

@@ -0,0 +1,95 @@
+/**
+	Internet IPv4 address
+	Used for socket connection over TCP/IP or UDP
+	Format -> A.B.C.D:port
+*/
+namespace crown
+{
+  
+namespace network
+{
+	class IPv4Address
+	{
+		public:
+		
+		// Default constructor
+		IPv4Address()
+		{
+			m_address = 0;
+			m_port = 0;
+		}
+		
+		// Constructor
+		IPv4Address(unsigned char a, unsigned char b, unsigned char c, unsigned char d, unsigned short port)
+		{
+			m_address = (a << 24) | (b << 16) | (c << 8) | d;
+			m_port = port;
+		}
+	
+		// Constructor	
+		IPv4Address(unsigned int address, unsigned short port)
+		{
+			m_address = address;
+			m_port = port;
+		}
+	
+		inline unsigned int get_address() const
+		{
+			return m_address;
+		}
+	
+		inline unsigned char get_a() const
+		{
+			return (unsigned char) (m_address >> 24);
+		}
+		
+		inline unsigned char get_b() const
+		{
+			return (unsigned char) (m_address >> 16);
+		}
+		
+		inline unsigned char get_c() const
+		{
+			return (unsigned char) (m_address >> 8);
+		}
+		
+		inline unsigned char get_d() const
+		{
+			return (unsigned char) (m_address);
+		}
+		
+		inline unsigned short get_port() const
+		{ 
+			return m_port;
+		}
+		
+		bool operator == (const IPv4Address& other) const
+		{
+			return m_address == other.m_address && m_port == other.m_port;
+		}
+		
+		bool operator != (const IPv4Address& other) const
+		{
+			return !(*this == other);
+		}
+		
+		bool operator < (const IPv4Address& other) const
+		{
+			// note: this is so we can use address as a key in std::map
+			if (m_address < other.m_address)
+				return true;
+			if (m_address > other.m_address)
+				return false;
+			else
+				return m_port < other.m_port;
+		}
+		
+		private:
+		
+			unsigned int 	m_address;
+			unsigned short 	m_port;
+	};
+}
+
+}
+

+ 11 - 0
src/network/Message.cpp

@@ -0,0 +1,11 @@
+#include "Message.h"
+
+namespace crown
+{
+
+namespace network
+{
+  
+}
+  
+}

+ 94 - 0
src/network/Message.h

@@ -0,0 +1,94 @@
+#pragma once
+
+#include "IPv4Address.h"
+
+namespace crown
+{
+  
+namespace network
+{
+	typedef unsigned char byte;
+	
+	class Vec3;
+	class Angle;
+	
+	class Message
+	{
+						Message();
+						~Message();
+
+		void			init(byte* data, int length);
+		void			init(const byte* data, int length);
+		byte*			get_data();								// get data for writing
+		const byte*		get_data() const;						// get data for reading
+		int				get_max_size() const;					// get the maximum message size
+
+		int				get_size() const;						// size of the message in bytes
+		void			set_size(int size);						// set the message size
+		int				get_write_bit() const;					// get current write bit
+		void			set_write_bit(int bit);					// set current write bit
+		int				get_num_bits_written() const;			// returns number of bits written
+		int				get_remaining_write_bits() const;		// space left in bits for writing
+		void			save_write_state(int& s, int& b) const;	// save the write state
+		void			restore_write_state(int s, int b);		// restore the write state
+
+		int				get_read_count() const;					// bytes read so far
+		void			set_read_count(int bytes);				// set the number of bytes and bits read
+		int				get_read_bit() const;					// get current read bit
+		void			set_read_bit(int bit);					// set current read bit
+		int				get_num_bits_read() const;				// returns number of bits read
+		int				get_remaining_read_bits() const;		// number of bits left to read
+		void			save_read_state(int& c, int& b) const;	// save the read state
+		void			restore_read_state(int c, int b);		// restore the read state
+
+		void			begin_writing();						// begin writing
+		int				get_remaining_space() const;			// space left in bytes
+		void			write_byte_align();						// write up to the next byte boundary
+		void			write_bits(int value, int num_bits);	// write the specified number of bits
+		void			write_char(int c);
+		void			write_byte(int c);
+		void			write_short(int c);
+		void			write_u_short(int c);
+		void			write_long(int c);
+		void			write_float(float f);
+		void			write_float(float f, int exponent_bits, int mantissa_bits);
+		void			write_angle(Angle angle);
+		void			write_vec3(const Vec3& dir, int num_bits);
+		void			write_string(const char* s, int max_length = -1, bool make7Bit = true );
+		void			write_data(const void* data, int length);
+		void			write_ipv4addr(const IPv4Address addr);
+
+		void			begin_reading() const;					// begin reading.
+		int				get_remaing_data() const;				// number of bytes left to read
+		void			read_byte_align() const;				// read up to the next byte boundary
+		int				read_bits(int num_bits) const;			// read the specified number of bits
+		int				read_char() const;
+		int				read_byte() const;
+		int				read_short() const;
+		int				read_u_short() const;
+		int				read_long() const;
+		float			read_float() const;
+		float			read_float(int exponent_bits, int mantissa_bits) const;
+		Angle			read_angle() const;
+		Vec3			read_vec3(int num_bits) const;
+		int				read_string(char* buffer, int buffer_size) const;
+		int				read_data(void* data, int length) const;
+		void			read_ipv4addr(IPv4Address* addr) const;
+
+		static int		vec3_to_bits(const Vec3& vec, int num_bits);
+		static Vec3		bits_to_vec3(int bits, int numBits);
+
+	private:
+		byte *			m_write_data;			// pointer to data for writing
+		const byte *	m_read_data;			// pointer to data for reading
+		int				m_max_size;				// maximum size of message in bytes
+		int				m_cur_size;				// current size of message in bytes
+		int				m_write_bit;			// number of bits written to the last written byte
+		mutable int		m_read_count;			// number of bytes read so far
+		mutable int		m_read_bit;				// number of bits read from the last read byte
+
+	private:
+		byte *			_get_byte_space(int length);
+	};
+}
+}

+ 34 - 0
src/network/NetCrown.h

@@ -0,0 +1,34 @@
+#pragma once
+
+// platform detection
+
+#define PLATFORM_UNIX		1
+#define PLATFORM_MAC		2
+#define PLATFORM_WINDOWS	3
+
+#if defined(_WIN32)
+#define PLATFORM PLATFORM_WINDOWS
+#elif defined(__APPLE__)
+#define PLATFORM PLATFORM_MAC
+#else
+#define PLATFORM PLATFORM_UNIX
+#endif
+
+#if PLATFORM == PLATFORM_WINDOWS
+
+	#include <winsock2.h>
+	#pragma comment( lib, "wsock32.lib" )
+
+#elif PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
+
+	#include <sys/socket.h>
+	#include <sys/types.h>
+	#include <netinet/in.h>
+	#include <fcntl.h>
+	#include <unistd.h>
+
+#else
+
+	#error unknown platform!
+
+#endif

+ 189 - 0
src/network/TCPSocket.cpp

@@ -0,0 +1,189 @@
+#include <iostream>
+#include <cassert>
+
+#include "NetCrown.h"
+#include "IPv4Address.h"
+#include "TCPSocket.h"
+
+namespace crown
+{
+
+namespace network
+{
+
+	TCPSocket::TCPSocket()
+	{
+		set_socket_id(0);
+		set_active_socket_id(0);
+	}
+
+	TCPSocket::~TCPSocket()
+	{
+		close();
+	}
+
+	bool TCPSocket::open(unsigned short port)
+	{
+		int sd = socket(AF_INET, SOCK_STREAM, 0);
+
+		if (sd <= 0)
+		{
+			std::cout << "failed to open socket\n" << std::endl;
+			set_socket_id(0);
+			return false;
+		}
+
+		set_socket_id(sd);
+
+		// Bind socket
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = htonl(INADDR_ANY);
+		address.sin_port = htons(port);
+
+		if (bind(sd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+		{
+			std::cout << "failed to bind socket\n" << std::endl;
+			close();
+			return false;
+		}
+
+		listen(sd, 5);
+		std::cout << "listening on port " << port << std::endl;
+
+		sockaddr_in client;
+		unsigned int client_length = sizeof(client);
+
+		int active_sd = accept(sd, (sockaddr*)&client, &client_length);
+		if (active_sd < 0)
+		{
+			std::cout << "Error on accept()" << std::endl;
+		}
+
+		set_active_socket_id(active_sd);
+
+		return true;
+	}
+
+	bool TCPSocket::connect(IPv4Address& destination)
+	{
+		int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+		if (sd <= 0)
+		{
+			std::cout << "failed to open socket\n" << std::endl;
+			set_socket_id(0);
+			return false;
+		}
+
+		set_socket_id(sd);
+
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr =  htonl(destination.get_address());
+		address.sin_port = htons(destination.get_port());
+
+		if (::connect(sd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+		{
+			std::cout << "failed to connect socket\n" << std::endl;
+			close();
+			return false;
+		}
+	}
+
+	int TCPSocket::close()
+	{
+		int asd = get_active_socket_id();
+		if (asd != 0)
+		{
+			#if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_MAC
+			::close(asd);
+			#elif PLATFORM == PLATFORM_WINDOWS
+			closesocket(asd);
+			#endif
+			set_active_socket_id(0);
+		}
+
+		int sd = get_socket_id();
+		if (sd != 0)
+		{
+			#if PLATFORM == PLATFORM_UNIX || PLATFORM == PLATFORM_MAC
+			::close(sd);
+			#elif PLATFORM == PLATFORM_WINDOWS
+			closesocket(sd);
+			#endif
+			set_socket_id(0);
+		}
+	}
+
+	bool TCPSocket::send(const void* data, int size)
+	{
+		assert(data);
+		assert(size > 0);
+
+		int sd = get_active_socket_id();
+		if (sd <= 0)
+		{
+			set_socket_id(0);
+			set_active_socket_id(0);
+			return false;
+		}
+
+		int sent_bytes = ::send(sd, (const char*)data, size, 0);
+		if (sent_bytes <= 0)
+		{
+			std::cout << "Unable to send data" << std::endl;
+			return false;
+		}
+
+		return true;
+	}
+
+	int TCPSocket::receive(void* data, int size)
+	{
+		assert(data);
+		assert(size > 0);
+
+		int sd = get_active_socket_id();
+
+		if ( sd <= 0 )
+		{
+			return false;
+		}
+
+		int received_bytes = recv(sd, (char*)data, size, 0);
+
+		if ( received_bytes <= 0 )
+		{
+			return 0;
+		}
+
+		return received_bytes;
+	}
+
+	bool TCPSocket::is_open()
+	{
+		return m_active_socket != 0 || m_socket != 0;
+	}
+	
+	inline int TCPSocket::get_socket_id() 
+	{ 
+		return m_socket; 
+	}
+
+	inline int TCPSocket::get_active_socket_id() 
+	{ 
+		return m_active_socket != 0 ? m_active_socket : m_socket; 
+	}
+
+	inline void TCPSocket::set_socket_id( int socket ) 
+	{ 
+		m_socket = socket; 
+	}
+	
+	inline void TCPSocket::set_active_socket_id( int socket ) 
+	{ 
+		m_active_socket = socket; 
+	}
+}
+}

+ 56 - 0
src/network/TCPSocket.h

@@ -0,0 +1,56 @@
+#pragma once
+
+namespace crown
+{
+
+namespace network
+{
+	class IPv4Address;
+
+	/**
+	// Abstraction of sys/socket which rapresents
+	// a TCP connection socket.
+	**/
+	class TCPSocket
+	{
+	public:
+
+					// Constructor
+					TCPSocket();
+					// Destructor
+					~TCPSocket();
+					// Open connection (server side)
+		bool 		open(unsigned short port);
+					// Connect (client side)
+		bool		connect(IPv4Address& destination);
+					// Close connection
+		int			close();
+					// Send data through socket
+		bool 		send(const void* data, int size);
+					// Receive data through socket
+		int			receive(void* data, int size);
+					// Is connection open?
+		bool 		is_open();
+					// Getter method for socket descriptor
+		int 		get_socket_id();
+					// Getter method for active socket descriptor
+		int 		get_active_socket_id();
+
+	protected:
+
+					// Setter method for socket descriptor
+		void 		set_socket_id(int socket);
+					// Setter method for ative socket descriptor
+		void 		set_active_socket_id(int socket);
+
+	private:
+
+					// Generated by ::socket
+		int 		m_socket;
+				  // Generated by ::accept
+		int 		m_active_socket;
+	};
+}
+}
+
+

+ 149 - 0
src/network/UDPSocket.cpp

@@ -0,0 +1,149 @@
+#include <iostream>
+#include <cassert>
+
+#include "NetCrown.h"
+#include "IPv4Address.h"
+#include "UDPSocket.h"
+
+namespace crown
+{
+  
+namespace network
+{
+	UDPSocket::UDPSocket()
+	{
+		m_socket = 0;
+	}
+
+	UDPSocket::~UDPSocket()
+	{
+		close();
+	}
+
+	bool UDPSocket::open(unsigned short port)
+	{
+		assert(!is_open());
+
+		m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		if (m_socket <= 0)
+		{
+			cout << "Failed to create socket." << endl;
+			m_socket = 0;
+			return false;
+		}
+
+		// bind to port
+
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = INADDR_ANY;
+		address.sin_port = htons(port);
+
+		if ( bind( m_socket, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+		{
+			cout << "Failed to bind socket" << endl;
+			close();
+			return false;
+		}
+
+		// set non-blocking io
+
+		#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
+
+		int non_blocking = 1;
+		if (fcntl( m_socket, F_SETFL, O_NONBLOCK, non_blocking ) == -1)
+		{
+			cout << "Failed to set non-blocking socket" << endl;
+			close();
+			return false;
+		}
+
+		#elif PLATFORM == PLATFORM_WINDOWS
+
+		DWORD non_blocking = 1;
+		if (ioctlsocket( socket, FIONBIO, &non_blocking ) != 0)
+		{
+			cout << "Failed to set non-blocking socket" << endl;
+			close();
+			return false;
+		}
+
+		#endif
+
+		return true;
+	}
+
+	bool UDPSocket::send(IPv4Address &receiver, const void* data, int size)
+	{
+		assert(data);
+		assert(size > 0);
+
+		if (m_socket == 0)
+		{
+			return false;
+		}
+	
+		assert(receiver.get_address() != 0);
+		assert(receiver.get_port() != 0);
+
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = htonl(receiver.get_address());
+		address.sin_port = htons(receiver.get_port());
+
+		int sent_bytes = sendto(m_socket, (const char*)data, size, 0, (sockaddr*)&address, sizeof(sockaddr_in));
+
+		return sent_bytes == size;
+	}
+
+	int UDPSocket::receive(IPv4Address &sender, void* data, int size)
+	{
+		assert(data);
+		assert(size > 0);
+
+		if (m_socket == 0)
+		{
+			return false;
+		}
+
+		#if PLATFORM == PLATFORM_WINDOWS
+		typedef int socklen_t;
+		#endif
+
+		sockaddr_in from;
+		socklen_t from_length = sizeof(from);
+
+		int received_bytes = recvfrom(m_socket, (char*)data, size, 0, (sockaddr*)&from, &from_length);
+
+		if (received_bytes <= 0)
+		{
+				return 0;
+		}
+
+		unsigned int address = ntohl(from.sin_addr.s_addr);
+		unsigned short port = ntohs(from.sin_port);
+
+		sender = IPv4Address(address, port);
+
+		return received_bytes;
+	}
+
+	void UDPSocket::close()
+	{
+		if ( m_socket != 0 )
+		{
+			#if PLATFORM == PLATFORM_MAC || PLATFORM == PLATFORM_UNIX
+			::close(m_socket);
+			#elif PLATFORM == PLATFORM_WINDOWS
+			closesocket(m_socket);
+			#endif
+			m_socket = 0;
+		}
+	}
+
+	bool UDPSocket::is_open()
+	{
+		return m_socket != 0;
+	}
+}
+}

+ 30 - 0
src/network/UDPSocket.h

@@ -0,0 +1,30 @@
+#pragma once
+
+namespace crown
+{
+	class IPv4Address;
+	
+	class UDPSocket
+	{
+	public:
+
+					// Constructor
+					UDPSocket();
+					// Destructor
+					~UDPSocket();
+					// Open connection
+		bool 		open(unsigned short port);
+					 // Send data through socket
+		bool 		send(IPv4Address &receiver, const void* data, int size );
+					// Receive data through socket
+		int 		receive(IPv4Address &sender, void* data, int size);
+					// Close connection
+		void 		close();
+					// Is connection open?
+		bool 		is_open();
+
+	private:
+					// Socket descriptor
+		int 		m_socket;
+	};	
+}

+ 100 - 3
src/os/OS.h

@@ -28,6 +28,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 #include "Config.h"
 #include "Str.h"
 #include "List.h"
+#include "Types.h"
 
 namespace crown
 {
@@ -42,8 +43,8 @@ namespace os
 #ifdef LINUX
 const size_t	MAX_OS_PATH_LENGTH = 1024;
 const char		PATH_SEPARATOR = '/';
-
 const size_t	MAX_OS_EVENTS = 512;
+
 #endif
 
 #ifdef WINDOWS
@@ -96,6 +97,7 @@ void			hide_cursor();
 void			show_cursor();
 
 //-----------------------------------------------------------------------------
+
 enum OSEventType
 {
 	OSET_NONE				= 0,
@@ -123,7 +125,102 @@ void				push_event(OSEventType type, int data_a, int data_b, int data_c, int dat
 //! Returns the event on top of the @a event_queue	
 OSEvent&			pop_event();
 
-} // namespace os
 
-} // namespace crown
 
+//-----------------------------------------------------------------------------
+//		Networking
+//-----------------------------------------------------------------------------
+
+struct IPv4Address
+{
+	uchar 	address[4];
+	ushort 	port;
+	
+	uint get_address()
+	{
+		uint addr = address[0] << 24 | address[1] << 16 | address[2] << 8 | address[3];
+		
+		return addr;
+	}
+	
+	ushort get_port()
+	{
+		return port;
+	}
+	
+	void set(uint a, ushort p)
+	{
+		address[0] = (uchar) a >> 24;
+		address[1] = (uchar) a >> 16;
+		address[2] = (uchar) a >> 8;
+		address[3] = (uchar) a;
+
+		port = p;
+	}
+};
+
+class UDPSocket
+{
+	public:
+
+					// Constructor
+					UDPSocket();
+					// Destructor
+					~UDPSocket();
+					// Open connection
+		bool 		open(ushort port);
+					 // Send data through socket
+		bool 		send(IPv4Address &receiver, const void* data, int size );
+					// Receive data through socket
+		int 		receive(IPv4Address &sender, void* data, int size);
+					// Close connection
+		void 		close();
+					// Is connection open?
+		bool 		is_open();
+
+	private:
+					// Socket descriptor
+		int 		m_socket;  
+};
+
+class TCPSocket
+{
+	public:
+
+					// Constructor
+					TCPSocket();
+					// Destructor
+					~TCPSocket();
+					// Open connection (server side)
+		bool 		open(ushort port);
+					// Connect (client side)
+		bool		connect(IPv4Address& destination);
+					// Close connection
+		int			close();
+					// Send data through socket
+		bool 		send(const void* data, int size);
+					// Receive data through socket
+		int			receive(void* data, int size);
+					// Is connection open?
+		bool 		is_open();
+					// Getter method for socket descriptor
+		int 		get_socket_id();
+					// Getter method for active socket descriptor
+		int 		get_active_socket_id();
+				  // Setter method for socket descriptor
+
+	private:
+
+		void 		set_socket_id(int socket);
+					// Setter method for ative socket descriptor
+		void 		set_active_socket_id(int socket);
+		
+					// Generated by ::socket
+		int 		m_socket;
+				  // Generated by ::accept
+		int 		m_active_socket;
+}; 
+
+} // namespace os
+
+} // namespace crown

+ 175 - 0
src/os/linux/TCPSocket.cpp

@@ -0,0 +1,175 @@
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cassert>
+
+#include "OS.h"
+
+namespace crown
+{
+namespace os
+{
+
+TCPSocket::TCPSocket()
+{
+	set_socket_id(0);
+	set_active_socket_id(0);
+}
+
+TCPSocket::~TCPSocket()
+{
+	close();
+}
+
+bool TCPSocket::open(ushort port)
+{
+	int sd = socket(AF_INET, SOCK_STREAM, 0);
+
+	if (sd <= 0)
+	{
+		os::printf("failed to open socket\n");
+		set_socket_id(0);
+		return false;
+	}
+
+	set_socket_id(sd);
+
+	// Bind socket
+	sockaddr_in address;
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(INADDR_ANY);
+	address.sin_port = htons(port);
+
+	if (bind(sd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+	{
+		os::printf("failed to bind socket\n");
+		close();
+		return false;
+	}
+
+	listen(sd, 5);
+	os::printf("listening on port %d\n", port);
+
+	sockaddr_in client;
+	uint client_length = sizeof(client);
+
+	int asd = accept(sd, (sockaddr*)&client, &client_length);
+	if (asd < 0)
+	{
+		os::printf("failed to accept connection\n");
+	}
+
+	set_active_socket_id(asd);
+
+	return true;  
+}
+
+bool TCPSocket::connect(IPv4Address& destination)
+{
+	int sd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+	if (sd <= 0)
+	{
+		os::printf("failed to open socket\n");
+		set_socket_id(0);
+		return false;
+	}
+
+	set_socket_id(sd);
+
+	sockaddr_in address;
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr =  htonl(destination.get_address());
+	address.sin_port = htons(destination.get_port());
+
+	if (::connect(sd, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+	{
+		os::printf("failed to connect socket\n");
+		close();
+		return false;
+	}  
+}
+
+int	TCPSocket::close()
+{
+	int asd = get_active_socket_id();
+	if (asd != 0)
+	{
+		::close(asd);
+		set_active_socket_id(0);  
+	}
+}
+
+bool TCPSocket::send(const void* data, int size)
+{
+	assert(data);
+	assert(size > 0);
+
+	int sd = get_active_socket_id();
+	if (sd <= 0)
+	{
+		set_socket_id(0);
+		set_active_socket_id(0);
+		return false;
+	}
+
+	int sent_bytes = ::send(sd, (const char*)data, size, 0);
+	if (sent_bytes <= 0)
+	{
+		os::printf("Unable to send data");
+		return false;
+	}
+
+	return true;  
+}
+
+int TCPSocket::receive(void* data, int size)
+{
+	assert(data);
+	assert(size > 0);
+
+	int sd = get_active_socket_id();
+
+	if ( sd <= 0 )
+	{
+		return false;
+	}
+
+	int received_bytes = ::recv(sd, (char*)data, size, 0);
+	if ( received_bytes <= 0 )
+	{
+		return 0;
+	}
+
+	return received_bytes;
+}
+
+bool TCPSocket::is_open()
+{
+	return m_active_socket != 0 || m_socket != 0;
+}
+
+int	TCPSocket::get_socket_id()
+{
+	return m_socket;
+}
+
+int	TCPSocket::get_active_socket_id()
+{
+	return m_active_socket;
+}
+
+void TCPSocket::set_socket_id(int socket)
+{
+	m_socket = socket;
+}
+
+void TCPSocket::set_active_socket_id(int socket)
+{
+	m_active_socket = socket;
+}
+		
+}
+}

+ 126 - 0
src/os/linux/UDPSocket.cpp

@@ -0,0 +1,126 @@
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <cassert>
+
+#include "OS.h"
+
+namespace crown
+{ 
+namespace os
+{
+
+UDPSocket::UDPSocket()
+{
+	m_socket = 0;  
+}
+UDPSocket::~UDPSocket()
+{
+	close();
+}
+
+bool UDPSocket::open(ushort port)
+{
+  		assert(!is_open());
+
+		m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+		if (m_socket <= 0)
+		{
+			os::printf("Failed to create socket.\n");;
+			m_socket = 0;
+			return false;
+		}
+
+		// bind to port
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = INADDR_ANY;
+		address.sin_port = htons(port);
+
+		if ( bind( m_socket, (const sockaddr*)&address, sizeof(sockaddr_in)) < 0)
+		{
+			os::printf("Failed to bind socket\n");
+			close();
+			return false;
+		}
+
+		int non_blocking = 1;
+		if (fcntl( m_socket, F_SETFL, O_NONBLOCK, non_blocking ) == -1)
+		{
+			os::printf("Failed to set non-blocking socket\n");
+			close();
+			return false;
+		}
+		
+		return true;
+}
+
+bool UDPSocket::send(IPv4Address &receiver, const void* data, int size)
+{
+	assert(data);
+	assert(size > 0);
+
+	if (m_socket == 0)
+	{
+		return false;
+	}
+	
+	assert(receiver.address);
+	assert(receiver.port);
+
+	sockaddr_in address;
+	address.sin_family = AF_INET;
+	address.sin_addr.s_addr = htonl(receiver.get_address());
+	address.sin_port = htons(receiver.get_port());
+
+	int sent_bytes = sendto(m_socket, (const char*)data, size, 0, (sockaddr*)&address, sizeof(sockaddr_in));
+
+	return sent_bytes == size;
+}
+
+int UDPSocket::receive(IPv4Address &sender, void* data, int size)
+{
+	assert(data);
+	assert(size > 0);
+
+	if (m_socket == 0)
+	{
+		return false;
+	}
+
+	sockaddr_in from;
+	socklen_t from_length = sizeof(from);
+
+	int received_bytes = recvfrom(m_socket, (char*)data, size, 0, (sockaddr*)&from, &from_length);
+
+	if (received_bytes <= 0)
+	{
+			return 0;
+	}
+
+	uint address = ntohl(from.sin_addr.s_addr);
+	ushort port = ntohs(from.sin_port);
+
+	sender.set(address, port);
+
+	return received_bytes;	
+}
+
+void UDPSocket::close()
+{
+	if ( m_socket != 0 )
+	{
+		::close(m_socket);
+		m_socket = 0; 
+	}
+}
+
+bool UDPSocket::is_open()
+{
+	return m_socket != 0;
+}
+
+} // namespace os
+} // namespace crown