Win32 fixes

This commit is contained in:
Jack Andersen 2017-01-06 22:25:13 -10:00
parent 5dc0f4928e
commit 2b3faddac1
1 changed files with 62 additions and 13 deletions

View File

@ -1,19 +1,26 @@
#ifndef ATHENA_SOCKET_HPP #ifndef ATHENA_SOCKET_HPP
#define ATHENA_SOCKET_HPP #define ATHENA_SOCKET_HPP
#include <sys/types.h> #ifndef _WIN32
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#else
#include <winsock2.h>
#include <Ws2tcpip.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <string> #include <string>
#include "Global.hpp" #include "Global.hpp"
namespace athena namespace jbus
{ {
namespace net namespace net
{ {
@ -51,10 +58,10 @@ class IPAddress
else else
{ {
/* Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx") */ /* Try to convert the address as a byte representation ("xxx.xxx.xxx.xxx") */
uint32_t ip = inet_addr(address.c_str()); struct in_addr addr;
if (ip != INADDR_NONE) if (inet_pton(AF_INET, address.c_str(), &addr) == 1)
{ {
m_address = ip; m_address = addr.s_addr;
m_valid = true; m_valid = true;
} }
else else
@ -68,9 +75,9 @@ class IPAddress
{ {
if (result) if (result)
{ {
ip = reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr.s_addr; addr = reinterpret_cast<sockaddr_in*>(result->ai_addr)->sin_addr;
freeaddrinfo(result); freeaddrinfo(result);
m_address = ip; m_address = addr.s_addr;
m_valid = true; m_valid = true;
} }
} }
@ -95,7 +102,12 @@ public:
/** Server-oriented TCP socket class derived from SFML */ /** Server-oriented TCP socket class derived from SFML */
class Socket class Socket
{ {
int m_socket = -1; #ifndef _WIN32
using SocketTp = int;
#else
using SocketTp = SOCKET;
#endif
SocketTp m_socket = -1;
bool m_isBlocking; bool m_isBlocking;
static sockaddr_in createAddress(uint32_t address, unsigned short port) static sockaddr_in createAddress(uint32_t address, unsigned short port)
@ -118,7 +130,7 @@ class Socket
if (isOpen()) if (isOpen())
return false; return false;
m_socket = socket(PF_INET, SOCK_STREAM, 0); m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_socket == -1) if (m_socket == -1)
{ {
atError("Can't allocate socket"); atError("Can't allocate socket");
@ -151,6 +163,20 @@ public:
Busy Busy
}; };
#ifdef _WIN32
static EResult LastWSAError()
{
switch (WSAGetLastError())
{
case WSAEWOULDBLOCK:
case WSAEALREADY:
return EResult::Busy;
default:
return EResult::Error;
}
}
#endif
Socket(bool blocking) Socket(bool blocking)
: m_isBlocking(blocking) {} : m_isBlocking(blocking) {}
~Socket() { close(); } ~Socket() { close(); }
@ -174,11 +200,16 @@ public:
void setBlocking(bool blocking) void setBlocking(bool blocking)
{ {
m_isBlocking = blocking; m_isBlocking = blocking;
#ifndef _WIN32
int status = fcntl(m_socket, F_GETFL); int status = fcntl(m_socket, F_GETFL);
if (m_isBlocking) if (m_isBlocking)
fcntl(m_socket, F_SETFL, status & ~O_NONBLOCK); fcntl(m_socket, F_SETFL, status & ~O_NONBLOCK);
else else
fcntl(m_socket, F_SETFL, status | O_NONBLOCK); fcntl(m_socket, F_SETFL, status | O_NONBLOCK);
#else
u_long b = blocking ? 0 : 1;
ioctlsocket(m_socket, FIONBIO, &b);
#endif
} }
bool isOpen() const { return m_socket != -1; } bool isOpen() const { return m_socket != -1; }
@ -217,9 +248,15 @@ public:
/* Check for errors */ /* Check for errors */
if (remoteSocket == -1) if (remoteSocket == -1)
{ {
#ifndef _WIN32
EResult res = (errno == EAGAIN) ? EResult::Busy : EResult::Error; EResult res = (errno == EAGAIN) ? EResult::Busy : EResult::Error;
if (res == EResult::Error) if (res == EResult::Error)
atError("Failed to accept incoming connection: %s", strerror(errno)); atError("Failed to accept incoming connection: %s", strerror(errno));
#else
EResult res = LastWSAError();
if (res == EResult::Error)
atError("Failed to accept incoming connection");
#endif
return res; return res;
} }
@ -251,7 +288,11 @@ public:
{ {
if (!isOpen()) if (!isOpen())
return; return;
#ifndef _WIN32
::close(m_socket); ::close(m_socket);
#else
closesocket(m_socket);
#endif
m_socket = -1; m_socket = -1;
} }
@ -265,7 +306,7 @@ public:
return EResult::Error; return EResult::Error;
/* Loop until every byte has been sent */ /* Loop until every byte has been sent */
ssize_t result = 0; int result = 0;
for (size_t sent = 0; sent < len; sent += result) for (size_t sent = 0; sent < len; sent += result)
{ {
/* Send a chunk of data */ /* Send a chunk of data */
@ -273,7 +314,11 @@ public:
/* Check for errors */ /* Check for errors */
if (result < 0) if (result < 0)
#ifndef _WIN32
return (errno == EAGAIN) ? EResult::Busy : EResult::Error; return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
#else
return LastWSAError();
#endif
} }
transferred = len; transferred = len;
@ -302,7 +347,11 @@ public:
int result = ::recv(m_socket, static_cast<char*>(buf), static_cast<int>(len), _flags); int result = ::recv(m_socket, static_cast<char*>(buf), static_cast<int>(len), _flags);
if (result < 0) if (result < 0)
#ifndef _WIN32
return (errno == EAGAIN) ? EResult::Busy : EResult::Error; return (errno == EAGAIN) ? EResult::Busy : EResult::Error;
#else
return LastWSAError();
#endif
else if (result == 0) else if (result == 0)
return EResult::Error; return EResult::Error;