Network: Add support for sending/receiving NetPacket over UDP/TCP
Former-commit-id: 5c09a5fa8b499e4204d2312f6d04d8554093a5a4
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#include <Nazara/Core/CallOnExit.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <limits>
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
#include <Nazara/Network/NetPacket.hpp>
|
||||
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
#include <Nazara/Network/Win32/SocketImpl.hpp>
|
||||
@@ -16,6 +16,8 @@
|
||||
#error Missing implementation: Socket
|
||||
#endif
|
||||
|
||||
#include <Nazara/Network/Debug.hpp>
|
||||
|
||||
namespace Nz
|
||||
{
|
||||
SocketState TcpClient::Connect(const IpAddress& remoteAddress)
|
||||
@@ -141,6 +143,66 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcpClient::ReceivePacket(NetPacket* packet)
|
||||
{
|
||||
//TODO: Every packet requires at least two Receive call, using an internal buffer of a fixed size would prevent this
|
||||
NazaraAssert(packet, "Invalid packet");
|
||||
|
||||
if (!m_pendingPacket.headerReceived)
|
||||
{
|
||||
m_pendingPacket.data.Resize(NetPacket::HeaderSize);
|
||||
|
||||
std::size_t received;
|
||||
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], NetPacket::HeaderSize - m_pendingPacket.received, &received))
|
||||
return false;
|
||||
|
||||
m_pendingPacket.received += received;
|
||||
|
||||
NazaraAssert(m_pendingPacket.received <= NetPacket::HeaderSize, "Received more data than header size");
|
||||
if (m_pendingPacket.received >= NetPacket::HeaderSize)
|
||||
{
|
||||
UInt16 size;
|
||||
if (!NetPacket::DecodeHeader(m_pendingPacket.data.GetConstBuffer(), &size, &m_pendingPacket.netcode))
|
||||
{
|
||||
m_lastError = SocketError_Packet;
|
||||
NazaraWarning("Invalid header data");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pendingPacket.data.Resize(size - NetPacket::HeaderSize);
|
||||
m_pendingPacket.headerReceived = true;
|
||||
m_pendingPacket.received = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// We may have just received the header now
|
||||
if (m_pendingPacket.headerReceived)
|
||||
{
|
||||
UInt16 packetSize = static_cast<UInt16>(m_pendingPacket.data.GetSize()); //< Total packet size
|
||||
|
||||
std::size_t received;
|
||||
if (!Receive(&m_pendingPacket.data[m_pendingPacket.received], packetSize - m_pendingPacket.received, &received))
|
||||
return false;
|
||||
|
||||
m_pendingPacket.received += received;
|
||||
|
||||
NazaraAssert(m_pendingPacket.received <= packetSize, "Received more data than packet size");
|
||||
if (m_pendingPacket.received >= packetSize)
|
||||
{
|
||||
// Okay we received the whole packet, copy it
|
||||
packet->Reset(m_pendingPacket.netcode, m_pendingPacket.data.GetConstBuffer(), m_pendingPacket.data.GetSize());
|
||||
|
||||
// And reset every state
|
||||
m_pendingPacket.data.Clear();
|
||||
m_pendingPacket.headerReceived = false;
|
||||
m_pendingPacket.received = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent)
|
||||
{
|
||||
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
|
||||
@@ -183,6 +245,20 @@ namespace Nz
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TcpClient::SendPacket(const NetPacket& packet)
|
||||
{
|
||||
std::size_t size = 0;
|
||||
const UInt8* ptr = static_cast<const UInt8*>(packet.OnSend(&size));
|
||||
if (!ptr)
|
||||
{
|
||||
m_lastError = SocketError_Packet;
|
||||
NazaraError("Failed to prepare packet");
|
||||
return false;
|
||||
}
|
||||
|
||||
return Send(ptr, size, nullptr);
|
||||
}
|
||||
|
||||
bool TcpClient::SetCursorPos(UInt64 offset)
|
||||
{
|
||||
NazaraError("SetCursorPos() cannot be used on sequential streams");
|
||||
@@ -215,7 +291,7 @@ namespace Nz
|
||||
}
|
||||
|
||||
SocketState newState = SocketImpl::Connect(m_handle, m_peerAddress, msTimeout, &m_lastError);
|
||||
NazaraAssert(newState != SocketState_Connecting, "Invalid internal return");
|
||||
NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); //< Connect cannot return Connecting is a timeout was specified
|
||||
|
||||
// Prevent valid peer address in non-connected state
|
||||
if (newState == SocketState_NotConnected)
|
||||
|
||||
Reference in New Issue
Block a user