|
|
@@ -69,24 +69,36 @@ struct TCPSocket
|
|
|
|
|
|
void open()
|
|
|
{
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
_socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
CE_ASSERT(_socket >= 0, "socket: errno = %d", errno);
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- _socket = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
CE_ASSERT(_socket >= 0, "socket: WSAGetLastError = %d", WSAGetLastError());
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+ void close()
|
|
|
+ {
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
+ if (_socket != 0)
|
|
|
+ {
|
|
|
+ ::close(_socket);
|
|
|
+ _socket = 0;
|
|
|
+ }
|
|
|
+#elif CROWN_PLATFORM_WINDOWS
|
|
|
+ if (_socket != INVALID_SOCKET)
|
|
|
+ {
|
|
|
+ ::closesocket(_socket);
|
|
|
+ _socket = INVALID_SOCKET;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
ConnectResult connect(const IPAddress& ip, u16 port)
|
|
|
{
|
|
|
close();
|
|
|
open();
|
|
|
|
|
|
- ConnectResult cr;
|
|
|
- cr.error = ConnectResult::NO_ERROR;
|
|
|
-
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
sockaddr_in addr_in;
|
|
|
addr_in.sin_family = AF_INET;
|
|
|
addr_in.sin_addr.s_addr = htonl(ip.address());
|
|
|
@@ -94,28 +106,20 @@ struct TCPSocket
|
|
|
|
|
|
int err = ::connect(_socket, (const sockaddr*)&addr_in, sizeof(sockaddr_in));
|
|
|
|
|
|
+ ConnectResult cr;
|
|
|
+ cr.error = ConnectResult::NO_ERROR;
|
|
|
+
|
|
|
if (err == 0)
|
|
|
return cr;
|
|
|
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
if (errno == ECONNREFUSED)
|
|
|
cr.error = ConnectResult::REFUSED;
|
|
|
else if (errno == ETIMEDOUT)
|
|
|
cr.error = ConnectResult::TIMEOUT;
|
|
|
else
|
|
|
cr.error = ConnectResult::UNKNOWN;
|
|
|
-
|
|
|
- return cr;
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- sockaddr_in addr_in;
|
|
|
- addr_in.sin_family = AF_INET;
|
|
|
- addr_in.sin_addr.s_addr = ::htonl(ip.address());
|
|
|
- addr_in.sin_port = ::htons(port);
|
|
|
-
|
|
|
- int err = ::connect(_socket, (const sockaddr*)&addr_in, sizeof(sockaddr_in));
|
|
|
-
|
|
|
- if (err == 0)
|
|
|
- return cr;
|
|
|
-
|
|
|
int wsaerr = WSAGetLastError();
|
|
|
if (wsaerr == WSAECONNREFUSED)
|
|
|
cr.error = ConnectResult::REFUSED;
|
|
|
@@ -123,9 +127,8 @@ struct TCPSocket
|
|
|
cr.error = ConnectResult::TIMEOUT;
|
|
|
else
|
|
|
cr.error = ConnectResult::UNKNOWN;
|
|
|
-
|
|
|
- return cr;
|
|
|
#endif
|
|
|
+ return cr;
|
|
|
}
|
|
|
|
|
|
bool bind(u16 port)
|
|
|
@@ -133,50 +136,42 @@ struct TCPSocket
|
|
|
close();
|
|
|
open();
|
|
|
set_reuse_address(true);
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
+
|
|
|
sockaddr_in address;
|
|
|
address.sin_family = AF_INET;
|
|
|
address.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
address.sin_port = htons(port);
|
|
|
|
|
|
int err = ::bind(_socket, (const sockaddr*)&address, sizeof(sockaddr_in));
|
|
|
+
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
CE_ASSERT(err == 0, "bind: errno = %d", errno);
|
|
|
- CE_UNUSED(err);
|
|
|
- return true;
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- sockaddr_in address;
|
|
|
- address.sin_family = AF_INET;
|
|
|
- address.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
- address.sin_port = htons(port);
|
|
|
-
|
|
|
- int err = ::bind(_socket, (const sockaddr*)&address, sizeof(sockaddr_in));
|
|
|
CE_ASSERT(err == 0, "bind: WSAGetLastError = %d", WSAGetLastError());
|
|
|
+#endif
|
|
|
CE_UNUSED(err);
|
|
|
return true;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
void listen(u32 max)
|
|
|
{
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
int err = ::listen(_socket, max);
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
CE_ASSERT(err == 0, "listen: errno = %d", errno);
|
|
|
- CE_UNUSED(err);
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- int err = ::listen(_socket, max);
|
|
|
CE_ASSERT(err == 0, "listen: WSAGetLastError = %d", WSAGetLastError());
|
|
|
- CE_UNUSED(err);
|
|
|
#endif
|
|
|
+ CE_UNUSED(err);
|
|
|
}
|
|
|
|
|
|
AcceptResult accept_internal(TCPSocket& c)
|
|
|
{
|
|
|
+ int err = ::accept(_socket, NULL, NULL);
|
|
|
+
|
|
|
AcceptResult ar;
|
|
|
ar.error = AcceptResult::NO_ERROR;
|
|
|
|
|
|
#if CROWN_PLATFORM_POSIX
|
|
|
- int err = ::accept(_socket, NULL, NULL);
|
|
|
-
|
|
|
if (err >= 0)
|
|
|
c._socket = err;
|
|
|
else if (err == -1 && errno == EBADF)
|
|
|
@@ -185,11 +180,7 @@ struct TCPSocket
|
|
|
ar.error = AcceptResult::NO_CONNECTION;
|
|
|
else
|
|
|
ar.error = AcceptResult::UNKNOWN;
|
|
|
-
|
|
|
- return ar;
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- SOCKET err = ::accept(_socket, NULL, NULL);
|
|
|
-
|
|
|
if (err != INVALID_SOCKET)
|
|
|
{
|
|
|
c._socket = err;
|
|
|
@@ -201,9 +192,8 @@ struct TCPSocket
|
|
|
ar.error = AcceptResult::NO_CONNECTION;
|
|
|
else
|
|
|
ar.error = AcceptResult::UNKNOWN;
|
|
|
-
|
|
|
- return ar;
|
|
|
#endif
|
|
|
+ return ar;
|
|
|
}
|
|
|
|
|
|
AcceptResult accept_nonblock(TCPSocket& c)
|
|
|
@@ -218,35 +208,18 @@ struct TCPSocket
|
|
|
return accept_internal(c);
|
|
|
}
|
|
|
|
|
|
- void close()
|
|
|
- {
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
- if (_socket != 0)
|
|
|
- {
|
|
|
- ::close(_socket);
|
|
|
- _socket = 0;
|
|
|
- }
|
|
|
-#elif CROWN_PLATFORM_WINDOWS
|
|
|
- if (_socket != INVALID_SOCKET)
|
|
|
- {
|
|
|
- ::closesocket(_socket);
|
|
|
- _socket = INVALID_SOCKET;
|
|
|
- }
|
|
|
-#endif
|
|
|
- }
|
|
|
-
|
|
|
ReadResult read_internal(void* data, u32 size)
|
|
|
{
|
|
|
ReadResult rr;
|
|
|
rr.error = ReadResult::NO_ERROR;
|
|
|
rr.bytes_read = 0;
|
|
|
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
char* buf = (char*)data;
|
|
|
u32 to_read = size;
|
|
|
|
|
|
while (to_read > 0)
|
|
|
{
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
ssize_t read_bytes = ::recv(_socket, buf, to_read, 0);
|
|
|
|
|
|
if (read_bytes == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
|
|
|
@@ -263,19 +236,7 @@ struct TCPSocket
|
|
|
rr.error = ReadResult::REMOTE_CLOSED;
|
|
|
return rr;
|
|
|
}
|
|
|
-
|
|
|
- buf += read_bytes;
|
|
|
- to_read -= read_bytes;
|
|
|
- rr.bytes_read += read_bytes;
|
|
|
- }
|
|
|
-
|
|
|
- return rr;
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- char* buf = (char*)data;
|
|
|
- u32 to_read = size;
|
|
|
-
|
|
|
- while (to_read > 0)
|
|
|
- {
|
|
|
int read_bytes = ::recv(_socket, buf, (int)to_read, 0);
|
|
|
|
|
|
if (read_bytes == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
|
|
|
@@ -290,14 +251,13 @@ struct TCPSocket
|
|
|
rr.error = ReadResult::REMOTE_CLOSED;
|
|
|
return rr;
|
|
|
}
|
|
|
-
|
|
|
+#endif
|
|
|
buf += read_bytes;
|
|
|
to_read -= read_bytes;
|
|
|
rr.bytes_read += read_bytes;
|
|
|
}
|
|
|
|
|
|
return rr;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
ReadResult read_nonblock(void* data, u32 size)
|
|
|
@@ -318,12 +278,12 @@ struct TCPSocket
|
|
|
wr.error = WriteResult::NO_ERROR;
|
|
|
wr.bytes_wrote = 0;
|
|
|
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
const char* buf = (const char*)data;
|
|
|
u32 to_send = size;
|
|
|
|
|
|
while (to_send > 0)
|
|
|
{
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
ssize_t bytes_wrote = ::send(_socket, (const char*)buf, to_send, 0);
|
|
|
|
|
|
if (bytes_wrote == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))
|
|
|
@@ -343,19 +303,7 @@ struct TCPSocket
|
|
|
wr.error = WriteResult::UNKNOWN;
|
|
|
return wr;
|
|
|
}
|
|
|
-
|
|
|
- buf += bytes_wrote;
|
|
|
- to_send -= bytes_wrote;
|
|
|
- wr.bytes_wrote += bytes_wrote;
|
|
|
- }
|
|
|
-
|
|
|
- return wr;
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- const char* buf = (const char*)data;
|
|
|
- u32 to_send = size;
|
|
|
-
|
|
|
- while (to_send > 0)
|
|
|
- {
|
|
|
int bytes_wrote = ::send(_socket, (const char*)buf, (int)to_send, 0);
|
|
|
|
|
|
if (bytes_wrote == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK)
|
|
|
@@ -377,14 +325,12 @@ struct TCPSocket
|
|
|
wr.error = WriteResult::UNKNOWN;
|
|
|
return wr;
|
|
|
}
|
|
|
-
|
|
|
+#endif
|
|
|
buf += bytes_wrote;
|
|
|
to_send -= bytes_wrote;
|
|
|
wr.bytes_wrote += bytes_wrote;
|
|
|
}
|
|
|
-
|
|
|
return wr;
|
|
|
-#endif
|
|
|
}
|
|
|
|
|
|
WriteResult write_nonblock(const void* data, u32 size)
|
|
|
@@ -413,13 +359,11 @@ struct TCPSocket
|
|
|
|
|
|
void set_reuse_address(bool reuse)
|
|
|
{
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
int optval = (int)reuse;
|
|
|
- int err = setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
|
|
|
+ int err = setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval));
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
CE_ASSERT(err == 0, "setsockopt: errno = %d", errno);
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- int optval = (int)reuse;
|
|
|
- int err = setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, (const char*)&optval, sizeof(optval));
|
|
|
CE_ASSERT(err == 0, "setsockopt: WSAGetLastError = %d", WSAGetLastError());
|
|
|
#endif
|
|
|
CE_UNUSED(err);
|
|
|
@@ -427,21 +371,18 @@ struct TCPSocket
|
|
|
|
|
|
void set_timeout(u32 seconds)
|
|
|
{
|
|
|
-#if CROWN_PLATFORM_POSIX
|
|
|
struct timeval timeout;
|
|
|
timeout.tv_sec = seconds;
|
|
|
timeout.tv_usec = 0;
|
|
|
- int err = setsockopt (_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
+#if CROWN_PLATFORM_POSIX
|
|
|
+ int err = setsockopt(_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
CE_ASSERT(err == 0, "setsockopt: errno: %d", errno);
|
|
|
- err = setsockopt (_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
+ err = setsockopt(_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
CE_ASSERT(err == 0, "setsockopt: errno: %d", errno);
|
|
|
#elif CROWN_PLATFORM_WINDOWS
|
|
|
- struct timeval timeout;
|
|
|
- timeout.tv_sec = seconds;
|
|
|
- timeout.tv_usec = 0;
|
|
|
- int err = setsockopt (_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
+ int err = setsockopt(_socket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
CE_ASSERT(err == 0, "setsockopt: WSAGetLastError: %d", WSAGetLastError());
|
|
|
- err = setsockopt (_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
+ err = setsockopt(_socket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
|
|
|
CE_ASSERT(err == 0, "setsockopt: WSAGetLastError: %d", WSAGetLastError());
|
|
|
#endif
|
|
|
CE_UNUSED(err);
|