2009-01-29 00:18:34 +08:00
|
|
|
/*
|
2010-01-07 04:37:29 +08:00
|
|
|
* DSFML - SFML Library wrapper for the D programming language.
|
|
|
|
* Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
|
|
|
|
* Copyright (C) 2010 Andreas Hollandt
|
2009-01-29 00:18:34 +08:00
|
|
|
*
|
2010-01-07 04:37:29 +08:00
|
|
|
* This software is provided 'as-is', without any express or
|
|
|
|
* implied warranty. In no event will the authors be held
|
|
|
|
* liable for any damages arising from the use of this software.
|
2009-01-29 00:18:34 +08:00
|
|
|
*
|
2010-01-07 04:37:29 +08:00
|
|
|
* Permission is granted to anyone to use this software for any purpose,
|
|
|
|
* including commercial applications, and to alter it and redistribute
|
|
|
|
* it freely, subject to the following restrictions:
|
2009-01-29 00:18:34 +08:00
|
|
|
*
|
2010-01-07 04:37:29 +08:00
|
|
|
* 1. The origin of this software must not be misrepresented;
|
|
|
|
* you must not claim that you wrote the original software.
|
|
|
|
* If you use this software in a product, an acknowledgment
|
|
|
|
* in the product documentation would be appreciated but
|
|
|
|
* is not required.
|
2009-01-29 00:18:34 +08:00
|
|
|
*
|
2010-01-07 04:37:29 +08:00
|
|
|
* 2. Altered source versions must be plainly marked as such,
|
|
|
|
* and must not be misrepresented as being the original software.
|
2009-01-29 00:18:34 +08:00
|
|
|
*
|
2010-01-07 04:37:29 +08:00
|
|
|
* 3. This notice may not be removed or altered from any
|
|
|
|
* source distribution.
|
2009-01-29 00:18:34 +08:00
|
|
|
*/
|
|
|
|
|
2010-04-21 03:51:48 +08:00
|
|
|
module dsfml.network.udpsocket;
|
2009-01-29 00:18:34 +08:00
|
|
|
|
|
|
|
import dsfml.network.ipaddress;
|
|
|
|
import dsfml.network.packet;
|
|
|
|
import dsfml.network.socketstatus;
|
|
|
|
|
|
|
|
import dsfml.system.common;
|
|
|
|
|
|
|
|
/**
|
2010-04-21 03:51:48 +08:00
|
|
|
* UdpSocket wraps a socket using UDP protocol to
|
2010-03-16 07:35:53 +08:00
|
|
|
* send data fastly (but with less safety)
|
|
|
|
*/
|
2010-04-21 03:51:48 +08:00
|
|
|
class UdpSocket : DSFMLObject
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
2010-03-16 07:35:53 +08:00
|
|
|
* Default constructor
|
|
|
|
*/
|
2010-01-07 04:37:29 +08:00
|
|
|
this()
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
super(sfUdpSocket_Create());
|
2009-01-29 00:18:34 +08:00
|
|
|
m_intermediatePacket = new Packet();
|
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
override void dispose()
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
sfUdpSocket_Destroy(m_ptr);
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Bind the socket to a specific port
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* port = Port to bind the socket to
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* True if operation has been successful
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool bind(ushort port)
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
|
|
|
m_port = port;
|
2010-04-21 03:51:48 +08:00
|
|
|
return cast(bool)sfUdpSocket_Bind(m_ptr, port);
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Unbind the socket from its previous port, if any
|
|
|
|
*
|
|
|
|
* Returns: True if operation has been successful
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool unbind()
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
|
|
|
m_port = 0;
|
2010-04-21 03:51:48 +08:00
|
|
|
return cast(bool)sfUdpSocket_Unbind(m_ptr, m_port);
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Send an array of bytes
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* data = bytes array to send
|
|
|
|
* address = Address of the computer to send the packet to
|
|
|
|
* port = Port to send the data to
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Status code
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
SocketStatus send(byte[] data, IPAddress address, ushort port)
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
return cast(SocketStatus) sfUdpSocket_Send(m_ptr, data.ptr, data.length, address, port);
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Receive an array of bytes.
|
|
|
|
* This function is blocking.
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* data = Pointer to a byte array to fill (make sure it is big enough)
|
|
|
|
* sizeReceived = Number of bytes received
|
|
|
|
* address = Address of the computer which sent the data
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Status code
|
|
|
|
*
|
|
|
|
* Remarks:
|
|
|
|
* Assert if data is null or length == 0
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
SocketStatus receive(byte[] data, out size_t sizeReceived, out IPAddress address)
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
SocketStatus ret = sfUdpSocket_Receive(m_ptr, data.ptr, data.length, &sizeReceived, &address);
|
2009-01-29 00:18:34 +08:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Send a packet of data
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* packetToSend = Packet to send
|
|
|
|
* address = Address of the computer to send the packet to
|
|
|
|
* port = Port to send the data to
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Status code
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
SocketStatus send(Packet packetToSend, IPAddress address, ushort port)
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-01-07 04:37:29 +08:00
|
|
|
byte[] dataArray = packetToSend.onSend();
|
|
|
|
m_intermediatePacket.append(dataArray);
|
2010-04-21 03:51:48 +08:00
|
|
|
SocketStatus stat = cast(SocketStatus)sfUdpSocket_SendPacket(m_ptr, m_intermediatePacket.nativePointer, address, port);
|
2009-01-29 00:18:34 +08:00
|
|
|
m_intermediatePacket.clear();
|
|
|
|
return stat;
|
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Receive a packet.
|
|
|
|
* This function is blocking.
|
|
|
|
*
|
|
|
|
* Params:
|
|
|
|
* packetToReceive = Packet to fill with received data
|
|
|
|
* address = Address of the computer which sent the packet
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Status code
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
SocketStatus receive(Packet packetToReceive, out IPAddress address)
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
SocketStatus ret = sfUdpSocket_ReceivePacket(m_ptr, m_intermediatePacket.nativePointer, &address);
|
2009-01-29 00:18:34 +08:00
|
|
|
packetToReceive.onReceive(m_intermediatePacket.getData);
|
|
|
|
m_intermediatePacket.clear();
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Check if the socket is in a valid state ; this function
|
|
|
|
* can be called any time to check if the socket is OK
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* True if the socket is valid
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
bool isValid()
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
return cast(bool)sfUdpSocket_IsValid(m_ptr);
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
/**
|
|
|
|
* Get the port the socket is currently bound to
|
|
|
|
*
|
|
|
|
* Returns:
|
|
|
|
* Current port (0 means the socket is not bound)
|
|
|
|
*/
|
|
|
|
ushort getPort()
|
2009-01-29 00:18:34 +08:00
|
|
|
{
|
|
|
|
return m_port;
|
|
|
|
}
|
|
|
|
|
|
|
|
package:
|
2010-03-16 07:35:53 +08:00
|
|
|
this (SFMLClass ptr)
|
2010-01-07 04:37:29 +08:00
|
|
|
{
|
|
|
|
super(ptr);
|
|
|
|
m_intermediatePacket = new Packet();
|
|
|
|
}
|
|
|
|
|
2009-01-29 00:18:34 +08:00
|
|
|
private:
|
2010-01-07 04:37:29 +08:00
|
|
|
Packet m_intermediatePacket;
|
2009-01-29 00:18:34 +08:00
|
|
|
ushort m_port;
|
|
|
|
|
|
|
|
// External ====================================================================
|
|
|
|
|
2010-01-07 04:37:29 +08:00
|
|
|
extern (C)
|
|
|
|
{
|
2010-04-21 03:51:48 +08:00
|
|
|
typedef SFMLClass function() pf_sfUdpSocket_Create;
|
|
|
|
typedef void function(SFMLClass) pf_sfUdpSocket_Destroy;
|
|
|
|
typedef int function(SFMLClass, ushort) pf_sfUdpSocket_Bind;
|
|
|
|
typedef int function(SFMLClass, ushort) pf_sfUdpSocket_Unbind;
|
|
|
|
typedef SocketStatus function(SFMLClass, byte*, size_t, IPAddress, ushort) pf_sfUdpSocket_Send;
|
|
|
|
typedef SocketStatus function(SFMLClass, byte*, size_t, size_t*, IPAddress*) pf_sfUdpSocket_Receive;
|
|
|
|
typedef SocketStatus function(SFMLClass, SFMLClass, IPAddress, ushort) pf_sfUdpSocket_SendPacket;
|
|
|
|
typedef SocketStatus function(SFMLClass, SFMLClass, IPAddress*) pf_sfUdpSocket_ReceivePacket;
|
|
|
|
typedef int function(SFMLClass) pf_sfUdpSocket_IsValid;
|
2010-01-07 04:37:29 +08:00
|
|
|
|
2010-04-21 03:51:48 +08:00
|
|
|
static pf_sfUdpSocket_Create sfUdpSocket_Create;
|
|
|
|
static pf_sfUdpSocket_Destroy sfUdpSocket_Destroy;
|
|
|
|
static pf_sfUdpSocket_Bind sfUdpSocket_Bind;
|
|
|
|
static pf_sfUdpSocket_Unbind sfUdpSocket_Unbind;
|
|
|
|
static pf_sfUdpSocket_Send sfUdpSocket_Send;
|
|
|
|
static pf_sfUdpSocket_Receive sfUdpSocket_Receive;
|
|
|
|
static pf_sfUdpSocket_SendPacket sfUdpSocket_SendPacket;
|
|
|
|
static pf_sfUdpSocket_ReceivePacket sfUdpSocket_ReceivePacket;
|
|
|
|
static pf_sfUdpSocket_IsValid sfUdpSocket_IsValid;
|
2010-01-07 04:37:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static this()
|
|
|
|
{
|
2010-01-07 04:25:45 +08:00
|
|
|
debug
|
|
|
|
DllLoader dll = DllLoader.load("csfml-network-d");
|
|
|
|
else
|
|
|
|
DllLoader dll = DllLoader.load("csfml-network");
|
2010-01-07 04:37:29 +08:00
|
|
|
|
2010-04-21 03:51:48 +08:00
|
|
|
sfUdpSocket_Bind = cast(pf_sfUdpSocket_Bind)dll.getSymbol("sfUdpSocket_Bind");
|
|
|
|
sfUdpSocket_Create = cast(pf_sfUdpSocket_Create)dll.getSymbol("sfUdpSocket_Create");
|
|
|
|
sfUdpSocket_Destroy = cast(pf_sfUdpSocket_Destroy)dll.getSymbol("sfUdpSocket_Destroy");
|
|
|
|
sfUdpSocket_IsValid = cast(pf_sfUdpSocket_IsValid)dll.getSymbol("sfUdpSocket_IsValid");
|
|
|
|
sfUdpSocket_Receive = cast(pf_sfUdpSocket_Receive)dll.getSymbol("sfUdpSocket_Receive");
|
|
|
|
sfUdpSocket_ReceivePacket = cast(pf_sfUdpSocket_ReceivePacket)dll.getSymbol("sfUdpSocket_ReceivePacket");
|
|
|
|
sfUdpSocket_Send = cast(pf_sfUdpSocket_Send)dll.getSymbol("sfUdpSocket_Send");
|
|
|
|
sfUdpSocket_SendPacket = cast(pf_sfUdpSocket_SendPacket)dll.getSymbol("sfUdpSocket_SendPacket");
|
|
|
|
sfUdpSocket_Unbind = cast(pf_sfUdpSocket_Unbind)dll.getSymbol("sfUdpSocket_Unbind");
|
2010-01-07 04:37:29 +08:00
|
|
|
}
|
2009-01-29 00:18:34 +08:00
|
|
|
}
|