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( 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)
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
is_connected = false;
|
||||
return Socket::Status::Disconnected;
|
||||
}
|
||||
else if(read <= 0)
|
||||
|
||||
@ -31,6 +31,9 @@ namespace fr
|
||||
|
||||
Socket::Status Socket::send(const Packet &packet)
|
||||
{
|
||||
if(!is_connected)
|
||||
return Socket::Disconnected;
|
||||
|
||||
//Get packet data
|
||||
std::string data = packet.get_buffer();
|
||||
|
||||
@ -45,6 +48,9 @@ namespace fr
|
||||
|
||||
Socket::Status Socket::receive(Packet &packet)
|
||||
{
|
||||
if(!is_connected)
|
||||
return Socket::Disconnected;
|
||||
|
||||
Socket::Status status;
|
||||
|
||||
//Try to read packet length
|
||||
@ -68,6 +74,9 @@ namespace fr
|
||||
|
||||
Socket::Status Socket::receive_all(void *dest, size_t size)
|
||||
{
|
||||
if(!is_connected)
|
||||
return Socket::Disconnected;
|
||||
|
||||
size_t bytes_read = 0;
|
||||
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