Bug fixes. Better syntax.
SocketReactor actually calls callbacks. receive_all no longer tries to access out of bound array indexes. fr::Packet constructor can now take as many arguments as you like and they'll be added to it automatically. Added bool fr::Packet<< operator overload.
This commit is contained in:
parent
70779fbe9c
commit
f74f1f1a94
@ -14,6 +14,28 @@ namespace fr
|
|||||||
class Packet
|
class Packet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
Packet() noexcept = default;
|
||||||
|
|
||||||
|
//Nasty constructor to allow things like Packet{1, 2, 3, "bob"}.
|
||||||
|
template <typename T, typename ...Args>
|
||||||
|
Packet(T const &part, Args &&...args)
|
||||||
|
{
|
||||||
|
add(part, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename ...Args>
|
||||||
|
void add(T const& part, Args &&...args)
|
||||||
|
{
|
||||||
|
*this << part;
|
||||||
|
add(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void add(T const part)
|
||||||
|
{
|
||||||
|
*this << part;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Gets the data added to the packet
|
* Gets the data added to the packet
|
||||||
*
|
*
|
||||||
@ -24,6 +46,26 @@ namespace fr
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adds a boolean variable to the packet
|
||||||
|
*/
|
||||||
|
inline Packet &operator<<(bool var)
|
||||||
|
{
|
||||||
|
buffer.resize(buffer.size() + sizeof(var));
|
||||||
|
memcpy(&buffer[buffer.size() - sizeof(var)], &var, sizeof(var));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extracts a boolean variable from the packet
|
||||||
|
*/
|
||||||
|
inline Packet &operator>>(bool &var)
|
||||||
|
{
|
||||||
|
memcpy(&var, &buffer[0], sizeof(var));
|
||||||
|
buffer.erase(0, sizeof(var));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Adds a 16bit variable to the packet
|
* Adds a 16bit variable to the packet
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -113,10 +113,10 @@ namespace fr
|
|||||||
* an error.
|
* an error.
|
||||||
*
|
*
|
||||||
* @param dest Where to read the data into
|
* @param dest Where to read the data into
|
||||||
* @param size The number of bytes to read
|
* @param buffer_size The number of bytes to read
|
||||||
* @return Operation status.
|
* @return Operation status.
|
||||||
*/
|
*/
|
||||||
Status receive_all(void *dest, size_t size);
|
Status receive_all(void *dest, size_t buffer_size);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Checks to see if we're connected to a socket or not
|
* Checks to see if we're connected to a socket or not
|
||||||
|
|||||||
@ -16,6 +16,7 @@ namespace fr
|
|||||||
class SocketReactor
|
class SocketReactor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
SocketReactor() noexcept = default;
|
||||||
SocketReactor(const SocketReactor&)=delete;
|
SocketReactor(const SocketReactor&)=delete;
|
||||||
SocketReactor(SocketReactor&&) noexcept = default;
|
SocketReactor(SocketReactor&&) noexcept = default;
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ namespace fr
|
|||||||
bool wait(std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
bool wait(std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::pair<fr::Socket&, std::function<void()>>> callbacks;
|
std::vector<std::pair<const fr::Socket*, std::function<void()>>> callbacks;
|
||||||
fr::SocketSelector socket_selector;
|
fr::SocketSelector socket_selector;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -61,11 +61,11 @@ public:
|
|||||||
* read in 'received'.
|
* read in 'received'.
|
||||||
*
|
*
|
||||||
* @param data Where to store the received data.
|
* @param data Where to store the received data.
|
||||||
* @param data_size The number of bytes to try and receive. Be sure that it's not larger than data.
|
* @param buffer_size The number of bytes to try and receive. Be sure that it's not larger than data.
|
||||||
* @param received Will be filled with the number of bytes actually received, might be less than you requested.
|
* @param received Will be filled with the number of bytes actually received, might be less than you requested.
|
||||||
* @return The status of the operation, if the socket has disconnected etc.
|
* @return The status of the operation, if the socket has disconnected etc.
|
||||||
*/
|
*/
|
||||||
virtual Status receive_raw(void *data, size_t data_size, size_t &received) override;
|
virtual Status receive_raw(void *data, size_t buffer_size, size_t &received) override;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Sets the connections remote address.
|
* Sets the connections remote address.
|
||||||
|
|||||||
@ -72,21 +72,23 @@ namespace fr
|
|||||||
return Socket::Status::Success;
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Status Socket::receive_all(void *dest, size_t size)
|
Socket::Status Socket::receive_all(void *dest, size_t buffer_size)
|
||||||
{
|
{
|
||||||
if(!is_connected)
|
if(!is_connected)
|
||||||
return Socket::Disconnected;
|
return Socket::Disconnected;
|
||||||
|
|
||||||
|
ssize_t bytes_remaining = buffer_size;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
while(bytes_read < size)
|
while(bytes_remaining > 0)
|
||||||
{
|
{
|
||||||
size_t read = 0;
|
size_t received = 0;
|
||||||
Socket::Status status = receive_raw((uintptr_t*)dest + bytes_read, size, read);
|
Status status = receive_raw((uintptr_t*)dest + bytes_read, (size_t)bytes_remaining, received);
|
||||||
if(status == Socket::Status::Success)
|
if(status != fr::Socket::Success)
|
||||||
bytes_read += read;
|
|
||||||
else
|
|
||||||
return status;
|
return status;
|
||||||
|
bytes_remaining -= received;
|
||||||
|
bytes_read += received;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Socket::Status::Success;
|
return Socket::Status::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
// Created by fred on 20/12/16.
|
// Created by fred on 20/12/16.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include "frnetlib/SocketReactor.h"
|
#include "frnetlib/SocketReactor.h"
|
||||||
|
|
||||||
namespace fr
|
namespace fr
|
||||||
@ -10,27 +11,33 @@ namespace fr
|
|||||||
void SocketReactor::add(const Socket &socket, std::function<void()> callback)
|
void SocketReactor::add(const Socket &socket, std::function<void()> callback)
|
||||||
{
|
{
|
||||||
socket_selector.add(socket);
|
socket_selector.add(socket);
|
||||||
|
callbacks.emplace_back(std::make_pair(&socket, callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketReactor::remove(const Socket &socket)
|
void SocketReactor::remove(const Socket &socket)
|
||||||
{
|
{
|
||||||
socket_selector.remove(socket);
|
socket_selector.remove(socket);
|
||||||
|
callbacks.erase(std::find_if(callbacks.begin(), callbacks.end(), [&](const std::pair<const fr::Socket*, std::function<void()>> &check) {
|
||||||
|
return check.first->get_socket_descriptor() == socket.get_socket_descriptor();
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SocketReactor::wait(std::chrono::milliseconds timeout)
|
bool SocketReactor::wait(std::chrono::milliseconds timeout)
|
||||||
{
|
{
|
||||||
|
bool found = false;
|
||||||
if(socket_selector.wait(timeout))
|
if(socket_selector.wait(timeout))
|
||||||
{
|
{
|
||||||
//Find which socket sent the activity
|
//Find which socket sent the activity
|
||||||
for(auto &callback : callbacks)
|
for(auto &callback : callbacks)
|
||||||
{
|
{
|
||||||
if(socket_selector.is_ready(callback.first))
|
if(socket_selector.is_ready(*callback.first))
|
||||||
{
|
{
|
||||||
//Call the socket's callback
|
//Call the socket's callback
|
||||||
callback.second();
|
callback.second();
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,10 +52,10 @@ namespace fr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Status TcpSocket::receive_raw(void *data, size_t data_size, size_t &received)
|
Socket::Status TcpSocket::receive_raw(void *data, size_t buffer_size, size_t &received)
|
||||||
{
|
{
|
||||||
received = 0;
|
received = 0;
|
||||||
if(unprocessed_buffer.size() < data_size)
|
if(unprocessed_buffer.size() < buffer_size)
|
||||||
{
|
{
|
||||||
//Read RECV_CHUNK_SIZE bytes into the recv buffer
|
//Read RECV_CHUNK_SIZE bytes into the recv buffer
|
||||||
ssize_t status = ::recv(socket_descriptor, recv_buffer.get(), RECV_CHUNK_SIZE, 0);
|
ssize_t status = ::recv(socket_descriptor, recv_buffer.get(), RECV_CHUNK_SIZE, 0);
|
||||||
@ -80,12 +80,12 @@ namespace fr
|
|||||||
return Socket::Status::Disconnected;
|
return Socket::Status::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(received > data_size)
|
if(received > buffer_size)
|
||||||
received = data_size;
|
received = buffer_size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
received = data_size;
|
received = buffer_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Copy data to where it needs to go
|
//Copy data to where it needs to go
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user