Implemented tcp sockets (only IPv4) and asynchronous IO (for sockets).
This commit is contained in:
100
source/mijin/net/socket.hpp
Normal file
100
source/mijin/net/socket.hpp
Normal file
@@ -0,0 +1,100 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(MIJIN_NET_SOCKET_HPP_INCLUDED)
|
||||
#define MIJIN_NET_SOCKET_HPP_INCLUDED 1
|
||||
|
||||
#include "../async/coroutine.hpp"
|
||||
#include "../io/stream.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
|
||||
//
|
||||
// public types
|
||||
//
|
||||
|
||||
class Socket
|
||||
{
|
||||
protected:
|
||||
Socket() noexcept = default;
|
||||
Socket(const Socket&) noexcept = default;
|
||||
Socket(Socket&&) noexcept = default;
|
||||
|
||||
Socket& operator=(const Socket&) noexcept = default;
|
||||
Socket& operator=(Socket&&) noexcept = default;
|
||||
public:
|
||||
virtual ~Socket() noexcept = default;
|
||||
|
||||
virtual Stream& getStream() noexcept = 0;
|
||||
};
|
||||
|
||||
class ServerSocket
|
||||
{
|
||||
protected:
|
||||
ServerSocket() noexcept = default;
|
||||
ServerSocket(const ServerSocket&) noexcept = default;
|
||||
ServerSocket(ServerSocket&&) noexcept = default;
|
||||
|
||||
ServerSocket& operator=(const ServerSocket&) noexcept = default;
|
||||
ServerSocket& operator=(ServerSocket&&) noexcept = default;
|
||||
public:
|
||||
virtual ~ServerSocket() noexcept = default;
|
||||
|
||||
virtual void close() noexcept = 0;
|
||||
virtual Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() noexcept = 0;
|
||||
};
|
||||
|
||||
class TCPStream : public Stream
|
||||
{
|
||||
private:
|
||||
int handle_ = -1;
|
||||
bool async_ = false;
|
||||
public:
|
||||
StreamError readRaw(std::span<std::uint8_t> buffer, const ReadOptions& options, std::size_t* outBytesRead) override;
|
||||
StreamError writeRaw(std::span<const std::uint8_t> buffer) override;
|
||||
mijin::Task<StreamError> c_readRaw(std::span<std::uint8_t> buffer, const ReadOptions& options, std::size_t *outBytesRead) override;
|
||||
mijin::Task<StreamError> c_writeRaw(std::span<const std::uint8_t> buffer) override;
|
||||
std::size_t tell() override;
|
||||
StreamError seek(std::intptr_t pos, SeekMode seekMode = SeekMode::ABSOLUTE) override;
|
||||
void flush() override;
|
||||
bool isAtEnd() override;
|
||||
StreamFeatures getFeatures() override;
|
||||
|
||||
StreamError open(const char* address, std::uint16_t port) noexcept;
|
||||
void close() noexcept;
|
||||
[[nodiscard]] bool isOpen() const noexcept { return handle_ >= 0; }
|
||||
private:
|
||||
void setAsync(bool async);
|
||||
|
||||
friend class TCPServerSocket;
|
||||
};
|
||||
|
||||
class TCPSocket : public Socket
|
||||
{
|
||||
private:
|
||||
TCPStream stream_;
|
||||
public:
|
||||
TCPStream& getStream() noexcept override;
|
||||
|
||||
StreamError open(const char* address, std::uint16_t port) noexcept { return stream_.open(address, port); }
|
||||
void close() noexcept { stream_.close(); }
|
||||
[[nodiscard]] bool isOpen() const noexcept { return stream_.isOpen(); }
|
||||
|
||||
friend class TCPServerSocket;
|
||||
};
|
||||
|
||||
class TCPServerSocket : public ServerSocket
|
||||
{
|
||||
private:
|
||||
int handle_ = -1;
|
||||
public:
|
||||
StreamError setup(const char* address, std::uint16_t port) noexcept;
|
||||
void close() noexcept override;
|
||||
[[nodiscard]] bool isListening() const noexcept { return handle_ >= 0; }
|
||||
|
||||
Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() noexcept override;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(MIJIN_NET_SOCKET_HPP_INCLUDED)
|
||||
Reference in New Issue
Block a user