Network/TcpClient: Make TcpClient a Stream
Former-commit-id: 2176748166ae84b609d5a336495e6ff3550a765d
This commit is contained in:
parent
6829863d81
commit
4721bf80c3
|
|
@ -55,7 +55,7 @@ namespace Nz
|
||||||
Stream& operator=(Stream&&) = default;
|
Stream& operator=(Stream&&) = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline Stream(UInt32 openMode);
|
inline Stream(UInt32 streamOptions = StreamOption_None, UInt32 openMode = OpenMode_NotOpen);
|
||||||
|
|
||||||
virtual void FlushStream() = 0;
|
virtual void FlushStream() = 0;
|
||||||
virtual std::size_t ReadBlock(void* buffer, std::size_t size) = 0;
|
virtual std::size_t ReadBlock(void* buffer, std::size_t size) = 0;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline Stream::Stream(UInt32 openMode) :
|
inline Stream::Stream(UInt32 streamOptions, UInt32 openMode) :
|
||||||
m_openMode(openMode),
|
m_openMode(openMode),
|
||||||
m_streamOptions(0)
|
m_streamOptions(streamOptions)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,13 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Signal.hpp>
|
#include <Nazara/Core/Signal.hpp>
|
||||||
|
#include <Nazara/Core/Stream.hpp>
|
||||||
#include <Nazara/Network/AbstractSocket.hpp>
|
#include <Nazara/Network/AbstractSocket.hpp>
|
||||||
#include <Nazara/Network/IpAddress.hpp>
|
#include <Nazara/Network/IpAddress.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class NAZARA_NETWORK_API TcpClient : public AbstractSocket
|
class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream
|
||||||
{
|
{
|
||||||
friend class TcpServer;
|
friend class TcpServer;
|
||||||
|
|
||||||
|
|
@ -30,9 +31,13 @@ namespace Nz
|
||||||
void EnableLowDelay(bool lowDelay);
|
void EnableLowDelay(bool lowDelay);
|
||||||
void EnableKeepAlive(bool keepAlive, UInt64 msTime = 10000, UInt64 msInterval = 1000);
|
void EnableKeepAlive(bool keepAlive, UInt64 msTime = 10000, UInt64 msInterval = 1000);
|
||||||
|
|
||||||
|
bool EndOfStream() const override;
|
||||||
|
|
||||||
|
UInt64 GetCursorPos() const override;
|
||||||
inline UInt64 GetKeepAliveInterval() const;
|
inline UInt64 GetKeepAliveInterval() const;
|
||||||
inline UInt64 GetKeepAliveTime() const;
|
inline UInt64 GetKeepAliveTime() const;
|
||||||
inline IpAddress GetRemoteAddress() const;
|
inline IpAddress GetRemoteAddress() const;
|
||||||
|
UInt64 GetSize() const override;
|
||||||
|
|
||||||
inline bool IsLowDelayEnabled() const;
|
inline bool IsLowDelayEnabled() const;
|
||||||
inline bool IsKeepAliveEnabled() const;
|
inline bool IsKeepAliveEnabled() const;
|
||||||
|
|
@ -41,13 +46,19 @@ namespace Nz
|
||||||
|
|
||||||
bool Send(const void* buffer, std::size_t size, std::size_t* sent);
|
bool Send(const void* buffer, std::size_t size, std::size_t* sent);
|
||||||
|
|
||||||
|
bool SetCursorPos(UInt64 offset) override;
|
||||||
|
|
||||||
bool WaitForConnected(UInt64 msTimeout = 3000);
|
bool WaitForConnected(UInt64 msTimeout = 3000);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void FlushStream() override;
|
||||||
|
|
||||||
void OnClose() override;
|
void OnClose() override;
|
||||||
void OnOpened() override;
|
void OnOpened() override;
|
||||||
|
|
||||||
|
std::size_t ReadBlock(void* buffer, std::size_t size) override;
|
||||||
void Reset(SocketHandle handle, const IpAddress& peerAddress);
|
void Reset(SocketHandle handle, const IpAddress& peerAddress);
|
||||||
|
std::size_t WriteBlock(const void* buffer, std::size_t size) override;
|
||||||
|
|
||||||
IpAddress m_peerAddress;
|
IpAddress m_peerAddress;
|
||||||
UInt64 m_keepAliveInterval;
|
UInt64 m_keepAliveInterval;
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ namespace Nz
|
||||||
{
|
{
|
||||||
inline TcpClient::TcpClient() :
|
inline TcpClient::TcpClient() :
|
||||||
AbstractSocket(SocketType_TCP),
|
AbstractSocket(SocketType_TCP),
|
||||||
|
Stream(StreamOption_Sequential),
|
||||||
m_keepAliveInterval(1000), //TODO: Query OS default value
|
m_keepAliveInterval(1000), //TODO: Query OS default value
|
||||||
m_keepAliveTime(7'200'000), //TODO: Query OS default value
|
m_keepAliveTime(7'200'000), //TODO: Query OS default value
|
||||||
m_isKeepAliveEnabled(false), //TODO: Query OS default value
|
m_isKeepAliveEnabled(false), //TODO: Query OS default value
|
||||||
|
|
@ -18,6 +19,7 @@ namespace Nz
|
||||||
|
|
||||||
inline TcpClient::TcpClient(TcpClient&& tcpClient) :
|
inline TcpClient::TcpClient(TcpClient&& tcpClient) :
|
||||||
AbstractSocket(std::move(tcpClient)),
|
AbstractSocket(std::move(tcpClient)),
|
||||||
|
Stream(std::move(tcpClient)),
|
||||||
m_peerAddress(std::move(tcpClient.m_peerAddress)),
|
m_peerAddress(std::move(tcpClient.m_peerAddress)),
|
||||||
m_keepAliveInterval(tcpClient.m_keepAliveInterval),
|
m_keepAliveInterval(tcpClient.m_keepAliveInterval),
|
||||||
m_keepAliveTime(tcpClient.m_keepAliveTime),
|
m_keepAliveTime(tcpClient.m_keepAliveTime),
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
File::File() :
|
File::File() :
|
||||||
Stream(OpenMode_NotOpen),
|
|
||||||
m_impl(nullptr)
|
m_impl(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -75,6 +74,8 @@ namespace Nz
|
||||||
m_impl->Close();
|
m_impl->Close();
|
||||||
delete m_impl;
|
delete m_impl;
|
||||||
m_impl = nullptr;
|
m_impl = nullptr;
|
||||||
|
|
||||||
|
m_openMode = OpenMode_NotOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -208,20 +209,18 @@ namespace Nz
|
||||||
if (m_filePath.IsEmpty())
|
if (m_filePath.IsEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (openMode != 0)
|
if (openMode == OpenMode_NotOpen)
|
||||||
m_openMode = openMode;
|
|
||||||
|
|
||||||
if (m_openMode == 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::unique_ptr<FileImpl> impl(new FileImpl(this));
|
std::unique_ptr<FileImpl> impl(new FileImpl(this));
|
||||||
if (!impl->Open(m_filePath, m_openMode))
|
if (!impl->Open(m_filePath, openMode))
|
||||||
{
|
{
|
||||||
ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut
|
ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut
|
||||||
NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError());
|
NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_openMode = openMode;
|
||||||
m_impl = impl.release();
|
m_impl = impl.release();
|
||||||
|
|
||||||
if (m_openMode & OpenMode_Text)
|
if (m_openMode & OpenMode_Text)
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,22 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TcpClient::EndOfStream() const
|
||||||
|
{
|
||||||
|
return QueryAvailableBytes() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 TcpClient::GetCursorPos() const
|
||||||
|
{
|
||||||
|
NazaraError("GetCursorPos() cannot be used on sequential streams");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 TcpClient::GetSize() const
|
||||||
|
{
|
||||||
|
return QueryAvailableBytes();
|
||||||
|
}
|
||||||
|
|
||||||
bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received)
|
bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received)
|
||||||
{
|
{
|
||||||
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
|
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
|
||||||
|
|
@ -165,6 +181,12 @@ namespace Nz
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TcpClient::SetCursorPos(UInt64 offset)
|
||||||
|
{
|
||||||
|
NazaraError("SetCursorPos() cannot be used on sequential streams");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool TcpClient::WaitForConnected(UInt64 msTimeout)
|
bool TcpClient::WaitForConnected(UInt64 msTimeout)
|
||||||
{
|
{
|
||||||
switch (m_state)
|
switch (m_state)
|
||||||
|
|
@ -209,10 +231,15 @@ namespace Nz
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TcpClient::FlushStream()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void TcpClient::OnClose()
|
void TcpClient::OnClose()
|
||||||
{
|
{
|
||||||
AbstractSocket::OnClose();
|
AbstractSocket::OnClose();
|
||||||
|
|
||||||
|
m_openMode = OpenMode_NotOpen;
|
||||||
m_peerAddress = IpAddress::Invalid;
|
m_peerAddress = IpAddress::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,12 +256,56 @@ namespace Nz
|
||||||
NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')');
|
NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')');
|
||||||
|
|
||||||
m_peerAddress = IpAddress::Invalid;
|
m_peerAddress = IpAddress::Invalid;
|
||||||
|
m_openMode = OpenMode_ReadWrite;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t TcpClient::ReadBlock(void* buffer, std::size_t size)
|
||||||
|
{
|
||||||
|
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
|
||||||
|
|
||||||
|
CallOnExit restoreBlocking;
|
||||||
|
if (!m_isBlockingEnabled)
|
||||||
|
{
|
||||||
|
SocketImpl::SetBlocking(m_handle, true);
|
||||||
|
restoreBlocking.Reset([this] ()
|
||||||
|
{
|
||||||
|
SocketImpl::SetBlocking(m_handle, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t received;
|
||||||
|
if (!Receive(buffer, size, &received))
|
||||||
|
received = 0;
|
||||||
|
|
||||||
|
return received;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress)
|
void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress)
|
||||||
{
|
{
|
||||||
Open(handle);
|
Open(handle);
|
||||||
m_peerAddress = peerAddress;
|
m_peerAddress = peerAddress;
|
||||||
|
m_openMode = OpenMode_ReadWrite;
|
||||||
UpdateState(SocketState_Connected);
|
UpdateState(SocketState_Connected);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::size_t TcpClient::WriteBlock(const void* buffer, std::size_t size)
|
||||||
|
{
|
||||||
|
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
|
||||||
|
|
||||||
|
CallOnExit restoreBlocking;
|
||||||
|
if (!m_isBlockingEnabled)
|
||||||
|
{
|
||||||
|
SocketImpl::SetBlocking(m_handle, true);
|
||||||
|
restoreBlocking.Reset([this] ()
|
||||||
|
{
|
||||||
|
SocketImpl::SetBlocking(m_handle, false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t sent;
|
||||||
|
if (!Send(buffer, size, &sent))
|
||||||
|
sent = 0;
|
||||||
|
|
||||||
|
return sent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue