Added ability to toggle socket blocking mode

This commit is contained in:
Fred Nicolson 2016-12-11 20:45:13 +00:00
parent eec630ed24
commit 27a88febfa
3 changed files with 40 additions and 12 deletions

View File

@ -67,6 +67,7 @@ inline void *get_sin_addr(struct sockaddr *sa)
#define SOCKET_ERROR -1
#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#endif

View File

@ -6,6 +6,7 @@
#define FRNETLIB_SOCKET_H
#include "NetworkEncoding.h"
#include "Packet.h"
namespace fr
@ -21,9 +22,11 @@ namespace fr
BindFailed = 3,
Disconnected = 4,
Error = 5,
WouldBlock = 6,
};
Socket()
: is_blocking(true)
{
}
@ -88,9 +91,33 @@ namespace fr
return socket_descriptor;
}
/*!
* Sets the socket to blocking or non-blocking.
*
* @param should_block True for blocking (default argument), false otherwise.
*/
inline virtual void set_blocking(bool should_block = true)
{
//Don't update it if we're already in that mode
if(should_block == is_blocking)
return;
//Different API calls needed for both windows and unix
#ifdef WIN32
u_long non_blocking = should_block ? 0 : 1;
ioctlsocket(socket_descriptor, FIONBIO, &non_blocking);
#else
int flags = fcntl(socket_descriptor, F_GETFL, 0);
fcntl(socket_descriptor, F_SETFL, is_blocking ? flags ^ O_NONBLOCK : flags ^= O_NONBLOCK);
#endif
is_blocking = should_block;
}
protected:
int32_t socket_descriptor;
std::string remote_address;
bool is_blocking;
};
}

View File

@ -44,19 +44,17 @@ namespace fr
{
sent += status;
}
else
else if(errno != EWOULDBLOCK && errno != EAGAIN) //Don't exit if the socket just couldn't block
{
if(status == -1)
{
return Socket::Status::Error;
}
else
{
is_connected = false;
return Socket::Status::Disconnected;
}
}
}
return Socket::Status::Success;
}
@ -122,16 +120,18 @@ namespace fr
}
else
{
if(status == -1)
if(errno == EWOULDBLOCK || errno == EAGAIN)
{
return Socket::Status::WouldBlock;
}
else if(status == -1)
{
return Socket::Status::Error;
}
else
{
is_connected = false;
return Socket::Status::Disconnected;
}
}
if(received > data_size)
received = data_size;