Added SocketReactor & fixes
Sockets will immediately return fr::Socket::Status::Disconnected if an attempt to send/receive data is made whilst the connection is closed. Added SocketReactor, which is effectively a little wrapper around fr::SocketSelector, but can automatically call a callback for a socket when data is received on it.
This commit is contained in:
parent
7017b64a15
commit
70779fbe9c
@ -17,7 +17,7 @@ endif()
|
|||||||
set( INCLUDE_PATH "${PROJECT_SOURCE_DIR}/include" )
|
set( INCLUDE_PATH "${PROJECT_SOURCE_DIR}/include" )
|
||||||
set( SOURCE_PATH "${PROJECT_SOURCE_DIR}/src" )
|
set( SOURCE_PATH "${PROJECT_SOURCE_DIR}/src" )
|
||||||
|
|
||||||
set(SOURCE_FILES main.cpp src/TcpSocket.cpp include/frnetlib/TcpSocket.h src/TcpListener.cpp include/frnetlib/TcpListener.h src/Socket.cpp include/frnetlib/Socket.h src/Packet.cpp include/frnetlib/Packet.h include/frnetlib/NetworkEncoding.h src/SocketSelector.cpp include/frnetlib/SocketSelector.h src/HttpSocket.cpp include/frnetlib/HttpSocket.h src/HttpRequest.cpp include/frnetlib/HttpRequest.h src/HttpResponse.cpp include/frnetlib/HttpResponse.h src/Http.cpp include/frnetlib/Http.h src/SSLSocket.cpp include/frnetlib/SSLSocket.h src/SSLListener.cpp include/frnetlib/SSLListener.h include/frnetlib/SSLContext.h)
|
set(SOURCE_FILES main.cpp src/TcpSocket.cpp include/frnetlib/TcpSocket.h src/TcpListener.cpp include/frnetlib/TcpListener.h src/Socket.cpp include/frnetlib/Socket.h src/Packet.cpp include/frnetlib/Packet.h include/frnetlib/NetworkEncoding.h src/SocketSelector.cpp include/frnetlib/SocketSelector.h src/HttpSocket.cpp include/frnetlib/HttpSocket.h src/HttpRequest.cpp include/frnetlib/HttpRequest.h src/HttpResponse.cpp include/frnetlib/HttpResponse.h src/Http.cpp include/frnetlib/Http.h src/SSLSocket.cpp include/frnetlib/SSLSocket.h src/SSLListener.cpp include/frnetlib/SSLListener.h include/frnetlib/SSLContext.h src/SocketReactor.cpp include/frnetlib/SocketReactor.h)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
|
|||||||
55
include/frnetlib/SocketReactor.h
Normal file
55
include/frnetlib/SocketReactor.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// Created by fred on 20/12/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef FRNETLIB_SOCKETREACTOR_H
|
||||||
|
#define FRNETLIB_SOCKETREACTOR_H
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <functional>
|
||||||
|
#include <vector>
|
||||||
|
#include "Socket.h"
|
||||||
|
#include "SocketSelector.h"
|
||||||
|
|
||||||
|
namespace fr
|
||||||
|
{
|
||||||
|
class SocketReactor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SocketReactor(const SocketReactor&)=delete;
|
||||||
|
SocketReactor(SocketReactor&&) noexcept = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Adds a socket to the selector. Note that SocketSelector
|
||||||
|
* does not keep a copy of the object, just a handle, it's
|
||||||
|
* up to you to store your fr::Sockets.
|
||||||
|
*
|
||||||
|
* @param socket The socket to add.
|
||||||
|
* @param callback A function to call when the socket shows activity. Remember to remove it from the reactor if the client has disconnected.
|
||||||
|
*/
|
||||||
|
void add(const Socket &socket, std::function<void()> callback);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Removes a socket from the socket selector.
|
||||||
|
*
|
||||||
|
* @param socket The socket to remove.
|
||||||
|
*/
|
||||||
|
void remove(const Socket &socket);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Waits for a socket to become ready.
|
||||||
|
*
|
||||||
|
* @param timeout The amount of time wait should block for before timing out.
|
||||||
|
* @return True if a socket is ready. False if it timed out.
|
||||||
|
*/
|
||||||
|
bool wait(std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::pair<fr::Socket&, std::function<void()>>> callbacks;
|
||||||
|
fr::SocketSelector socket_selector;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //FRNETLIB_SOCKETREACTOR_H
|
||||||
@ -65,6 +65,7 @@ namespace fr
|
|||||||
|
|
||||||
if(read == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
|
if(read == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY)
|
||||||
{
|
{
|
||||||
|
is_connected = false;
|
||||||
return Socket::Status::Disconnected;
|
return Socket::Status::Disconnected;
|
||||||
}
|
}
|
||||||
else if(read <= 0)
|
else if(read <= 0)
|
||||||
|
|||||||
@ -31,6 +31,9 @@ namespace fr
|
|||||||
|
|
||||||
Socket::Status Socket::send(const Packet &packet)
|
Socket::Status Socket::send(const Packet &packet)
|
||||||
{
|
{
|
||||||
|
if(!is_connected)
|
||||||
|
return Socket::Disconnected;
|
||||||
|
|
||||||
//Get packet data
|
//Get packet data
|
||||||
std::string data = packet.get_buffer();
|
std::string data = packet.get_buffer();
|
||||||
|
|
||||||
@ -45,6 +48,9 @@ namespace fr
|
|||||||
|
|
||||||
Socket::Status Socket::receive(Packet &packet)
|
Socket::Status Socket::receive(Packet &packet)
|
||||||
{
|
{
|
||||||
|
if(!is_connected)
|
||||||
|
return Socket::Disconnected;
|
||||||
|
|
||||||
Socket::Status status;
|
Socket::Status status;
|
||||||
|
|
||||||
//Try to read packet length
|
//Try to read packet length
|
||||||
@ -68,6 +74,9 @@ namespace fr
|
|||||||
|
|
||||||
Socket::Status Socket::receive_all(void *dest, size_t size)
|
Socket::Status Socket::receive_all(void *dest, size_t size)
|
||||||
{
|
{
|
||||||
|
if(!is_connected)
|
||||||
|
return Socket::Disconnected;
|
||||||
|
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
while(bytes_read < size)
|
while(bytes_read < size)
|
||||||
{
|
{
|
||||||
|
|||||||
36
src/SocketReactor.cpp
Normal file
36
src/SocketReactor.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Created by fred on 20/12/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "frnetlib/SocketReactor.h"
|
||||||
|
|
||||||
|
namespace fr
|
||||||
|
{
|
||||||
|
|
||||||
|
void SocketReactor::add(const Socket &socket, std::function<void()> callback)
|
||||||
|
{
|
||||||
|
socket_selector.add(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketReactor::remove(const Socket &socket)
|
||||||
|
{
|
||||||
|
socket_selector.remove(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SocketReactor::wait(std::chrono::milliseconds timeout)
|
||||||
|
{
|
||||||
|
if(socket_selector.wait(timeout))
|
||||||
|
{
|
||||||
|
//Find which socket sent the activity
|
||||||
|
for(auto &callback : callbacks)
|
||||||
|
{
|
||||||
|
if(socket_selector.is_ready(callback.first))
|
||||||
|
{
|
||||||
|
//Call the socket's callback
|
||||||
|
callback.second();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user