Browse Source

Merge TCPServer into TCPSocket

Daniele Bartolini 11 năm trước cách đây
mục cha
commit
c69c6144b8
3 tập tin đã thay đổi với 139 bổ sung163 xóa
  1. 1 1
      engine/console_server.cpp
  2. 1 1
      engine/console_server.h
  3. 137 161
      engine/core/network/socket.h

+ 1 - 1
engine/console_server.cpp

@@ -43,7 +43,7 @@ namespace crown
 //-----------------------------------------------------------------------------
 void ConsoleServer::init(uint16_t port, bool wait)
 {
-	m_server.open(port);
+	m_server.bind(port);
 	m_server.listen(5);
 
 	if (wait)

+ 1 - 1
engine/console_server.h

@@ -92,7 +92,7 @@ private:
 
 private:
 
-	TCPServer m_server;
+	TCPSocket m_server;
 	ClientArray m_clients;
 };
 

+ 137 - 161
engine/core/network/socket.h

@@ -58,6 +58,11 @@ OTHER DEALINGS IN THE SOFTWARE.
 namespace crown
 {
 
+struct ConnectResult
+{
+	enum { NO_ERROR, REFUSED, TIMEOUT, UNKNOWN } error;
+};
+
 struct ReadResult
 {
 	enum { NO_ERROR, REMOTE_CLOSED, TIMEOUT, UNKNOWN } error;
@@ -90,25 +95,112 @@ struct TCPSocket
 	}
 
 	//-----------------------------------------------------------------------------
-	bool connect(const NetAddress& destination, uint16_t port)
+	ConnectResult connect(const NetAddress& destination, uint16_t port)
 	{
+		close();
 		m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-		CE_ASSERT(m_socket > 0, "Failed to create socket");
+		CE_ASSERT(m_socket >= 0, "socket: errno = %d", errno);
 
 		sockaddr_in addr_in;
 		addr_in.sin_family = AF_INET;
 		addr_in.sin_addr.s_addr = htonl(destination.address());
 		addr_in.sin_port = htons(port);
 
-		if (::connect(m_socket, (const sockaddr*)&addr_in, sizeof(sockaddr_in)) < 0)
+		int res = ::connect(m_socket, (const sockaddr*)&addr_in, sizeof(sockaddr_in));
+
+		ConnectResult cr;
+		cr.error = ConnectResult::NO_ERROR;
+
+		if (res == 0)
+			return cr;
+
+		if (errno == ECONNREFUSED)
+			cr.error = ConnectResult::REFUSED;
+		else if (errno == ETIMEDOUT)
+			cr.error = ConnectResult::TIMEOUT;
+		else
+			cr.error = ConnectResult::UNKNOWN;
+
+		return cr;
+	}
+
+	//-----------------------------------------------------------------------------
+	bool bind(uint16_t port)
+	{
+		close();
+		m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+		CE_ASSERT(m_socket >= 0, "socket: errno = %d", errno);
+
+		sockaddr_in address;
+		address.sin_family = AF_INET;
+		address.sin_addr.s_addr = htonl(INADDR_ANY);
+		address.sin_port = htons(port);
+
+		set_resuse_address(true);
+		int bind_ret = ::bind(m_socket, (const sockaddr*) &address, sizeof(sockaddr_in));
+		CE_ASSERT(bind_ret != -1, "bind: errno = %d", errno);
+		CE_UNUSED(bind_ret);
+
+		return true;
+	}
+
+	//-----------------------------------------------------------------------------
+	void listen(uint32_t max)
+	{
+		int listen_ret = ::listen(m_socket, max);
+		CE_ASSERT(listen_ret != -1, "listen: errno = %d", errno);
+		CE_UNUSED(listen_ret);
+	}
+
+	//-----------------------------------------------------------------------------
+	AcceptResult accept_nonblock(TCPSocket& c)
+	{
+		set_blocking(false);
+
+		sockaddr_in client;
+		size_t client_size = sizeof(client);
+		int sock = ::accept(m_socket, (sockaddr*) &client, (socklen_t*) &client_size);
+
+		AcceptResult result;
+		if (sock == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
 		{
-			os::printf("Failed to connect socket\n");
-			close();
+			result.error = AcceptResult::NO_CONNECTION;
+		}
+		else if (sock == -1)
+		{
+			result.error = AcceptResult::UNKNOWN;
+		}
+		else
+		{
+			result.error = AcceptResult::NO_ERROR;
+			c.m_socket = sock;
+		}
 
-			return false;
+		return result;
+	}
+
+	//-----------------------------------------------------------------------------
+	AcceptResult accept(TCPSocket& c)
+	{
+		set_blocking(true);
+
+		sockaddr_in client;
+		size_t client_size = sizeof(client);
+
+		int sock = ::accept(m_socket, (sockaddr*) &client, (socklen_t*) &client_size);
+
+		AcceptResult result;
+		if (sock == -1)
+		{
+			result.error = AcceptResult::UNKNOWN;
+		}
+		else
+		{
+			result.error = AcceptResult::NO_ERROR;
+			c.m_socket = sock;
 		}
 
-		return true;
+		return result;
 	}
 
 	//-----------------------------------------------------------------------------
@@ -127,27 +219,27 @@ struct TCPSocket
 		set_blocking(false);
 		ssize_t read_bytes = ::read(m_socket, (char*) data, size);
 
-		ReadResult result;
+		ReadResult rr;
 		if (read_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
 		{
-			result.error = ReadResult::NO_ERROR;
-			result.bytes_read = 0;
+			rr.error = ReadResult::NO_ERROR;
+			rr.bytes_read = 0;
 		}
 		else if (read_bytes == -1 && errno == ETIMEDOUT)
 		{
-			result.error = ReadResult::TIMEOUT;
+			rr.error = ReadResult::TIMEOUT;
 		}
 		else if (read_bytes == 0)
 		{
-			result.error = ReadResult::REMOTE_CLOSED;
+			rr.error = ReadResult::REMOTE_CLOSED;
 		}
 		else
 		{
-			result.error = ReadResult::NO_ERROR;
-			result.bytes_read = read_bytes;
+			rr.error = ReadResult::NO_ERROR;
+			rr.bytes_read = read_bytes;
 		}
 
-		return result;
+		return rr;
 	}
 
 	//-----------------------------------------------------------------------------
@@ -158,9 +250,9 @@ struct TCPSocket
 		// Ensure all data is read
 		char* buf = (char*) data;
 		size_t to_read = size;
-		ReadResult result;
-		result.bytes_read = 0;
-		result.error = ReadResult::NO_ERROR;
+		ReadResult rr;
+		rr.bytes_read = 0;
+		rr.error = ReadResult::NO_ERROR;
 
 		while (to_read > 0)
 		{
@@ -169,22 +261,22 @@ struct TCPSocket
 			if (read_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) continue;
 			else if (read_bytes == -1 && errno == ETIMEDOUT)
 			{
-				result.error = ReadResult::TIMEOUT;
-				return result;
+				rr.error = ReadResult::TIMEOUT;
+				return rr;
 			}
 			else if (read_bytes == 0)
 			{
-				result.error = ReadResult::REMOTE_CLOSED;
-				return result;
+				rr.error = ReadResult::REMOTE_CLOSED;
+				return rr;
 			}
 
 			buf += read_bytes;
 			to_read -= read_bytes;
-			result.bytes_read += read_bytes;
+			rr.bytes_read += read_bytes;
 		}
 
-		result.error = ReadResult::NO_ERROR;
-		return result;
+		rr.error = ReadResult::NO_ERROR;
+		return rr;
 	}
 
 	//-----------------------------------------------------------------------------
@@ -193,26 +285,26 @@ struct TCPSocket
 		set_blocking(false);
 		ssize_t bytes_wrote = ::send(m_socket, data, size, 0);
 
-		WriteResult result;
+		WriteResult wr;
 		if (bytes_wrote == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
 		{
-			result.error = WriteResult::NO_ERROR;
-			result.bytes_wrote = 0;
+			wr.error = WriteResult::NO_ERROR;
+			wr.bytes_wrote = 0;
 		}
 		else if (bytes_wrote == -1 && errno == ETIMEDOUT)
 		{
-			result.error = WriteResult::TIMEOUT;
+			wr.error = WriteResult::TIMEOUT;
 		}
 		else if (bytes_wrote == 0)
 		{
-			result.error = WriteResult::REMOTE_CLOSED;
+			wr.error = WriteResult::REMOTE_CLOSED;
 		}
 		else
 		{
-			result.error = WriteResult::UNKNOWN;
+			wr.error = WriteResult::UNKNOWN;
 		}
 
-		return result;
+		return wr;
 	}
 
 	//-----------------------------------------------------------------------------
@@ -222,9 +314,9 @@ struct TCPSocket
 
 		const char* buf = (const char*) data;
 		size_t to_send = size;
-		WriteResult result;
-		result.bytes_wrote = 0;
-		result.error = WriteResult::NO_ERROR;
+		WriteResult wr;
+		wr.bytes_wrote = 0;
+		wr.error = WriteResult::NO_ERROR;
 
 		// Ensure all data is sent
 		while (to_send > 0)
@@ -242,24 +334,24 @@ struct TCPSocket
 					}
 					case ETIMEDOUT:
 					{
-						result.error = WriteResult::TIMEOUT;
-						return result;
+						wr.error = WriteResult::TIMEOUT;
+						return wr;
 					}
 					default:
 					{
-						result.error = WriteResult::UNKNOWN;
-						return result;
+						wr.error = WriteResult::UNKNOWN;
+						return wr;
 					}
 				}
 			}
 
 			buf += bytes_wrote;
 			to_send -= bytes_wrote;
-			result.bytes_wrote += bytes_wrote;
+			wr.bytes_wrote += bytes_wrote;
 		}
 
-		result.error = WriteResult::NO_ERROR;
-		return result;
+		wr.error = WriteResult::NO_ERROR;
+		return wr;
 	}
 
 	//-----------------------------------------------------------------------------
@@ -284,132 +376,16 @@ struct TCPSocket
 		timeout.tv_usec = 0;
 		int res;
 		res = setsockopt (m_socket, SOL_SOCKET, SO_RCVTIMEO, (char*) &timeout, sizeof(timeout));
-		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
+		CE_ASSERT(res == 0, "setsockopt: errno: %d", errno);
 		res = setsockopt (m_socket, SOL_SOCKET, SO_SNDTIMEO, (char*) &timeout, sizeof(timeout));
-		CE_ASSERT(res == 0, "Failed to set timeout on socket: errno: %d", errno);
+		CE_ASSERT(res == 0, "setsockopt: errno: %d", errno);
 	}
 
-public:
+private:
 
 	int m_socket;
 };
 
-struct TCPServer
-{
-	//-----------------------------------------------------------------------------
-	bool open(uint16_t port)
-	{
-		m_server.m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-		CE_ASSERT(m_server.m_socket > 0, "Failed to create socket");
-
-		m_server.set_resuse_address(true);
-
-		// Bind socket
-		sockaddr_in address;
-		address.sin_family = AF_INET;
-		address.sin_addr.s_addr = htonl(INADDR_ANY);
-		address.sin_port = htons(port);
-
-		int bind_ret = bind(m_server.m_socket, (const sockaddr*) &address, sizeof(sockaddr_in));
-		CE_ASSERT(bind_ret != -1, "Failed to bind socket: errno: %d", errno);
-		CE_UNUSED(bind_ret);
-
-		return true;
-	}
-
-	//-----------------------------------------------------------------------------
-	void close()
-	{
-		m_server.close();
-	}
-
-	//-----------------------------------------------------------------------------
-	void listen(uint32_t max)
-	{
-		int listen_ret = ::listen(m_server.m_socket, max);
-		CE_ASSERT(listen_ret != -1, "Failed to listen on socket: errno: %d", errno);
-		CE_UNUSED(listen_ret);
-	}
-
-	//-----------------------------------------------------------------------------
-	AcceptResult accept_nonblock(TCPSocket& c)
-	{
-		m_server.set_blocking(false);
-
-		sockaddr_in client;
-		size_t client_size = sizeof(client);
-		int sock = ::accept(m_server.m_socket, (sockaddr*) &client, (socklen_t*) &client_size);
-
-		AcceptResult result;
-		if (sock == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
-		{
-			result.error = AcceptResult::NO_CONNECTION;
-		}
-		else if (sock == -1)
-		{
-			result.error = AcceptResult::UNKNOWN;
-		}
-		else
-		{
-			result.error = AcceptResult::NO_ERROR;
-			c.m_socket = sock;
-		}
-
-		return result;
-	}
-
-	//-----------------------------------------------------------------------------
-	AcceptResult accept(TCPSocket& c)
-	{
-		m_server.set_blocking(true);
-
-		sockaddr_in client;
-		size_t client_size = sizeof(client);
-
-		int sock = ::accept(m_server.m_socket, (sockaddr*) &client, (socklen_t*) &client_size);
-
-		AcceptResult result;
-		if (sock == -1)
-		{
-			result.error = AcceptResult::UNKNOWN;
-		}
-		else
-		{
-			result.error = AcceptResult::NO_ERROR;
-			c.m_socket = sock;
-		}
-
-		return result;
-	}
-
-	//-----------------------------------------------------------------------------
-	ReadResult read_nonblock(void* data, size_t size)
-	{
-		return m_server.read_nonblock(data, size);
-	}
-
-	//-----------------------------------------------------------------------------
-	ReadResult read(void* data, size_t size)
-	{
-		return m_server.read(data, size);
-	}
-
-	//-----------------------------------------------------------------------------
-	WriteResult write_nonblock(void* data, size_t size)
-	{
-		return m_server.write_nonblock(data, size);
-	}
-
-	//-----------------------------------------------------------------------------
-	WriteResult write(const void* data, size_t size)
-	{
-		return m_server.write(data, size);
-	}
-
-private:
-
-	TCPSocket m_server;
-};
 
 /*
 class TCPSocket