/* * DSFML - SFML Library wrapper for the D programming language. * Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com) * Copyright (C) 2010 Andreas Hollandt * * 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. * * 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: * * 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. * * 2. Altered source versions must be plainly marked as such, * and must not be misrepresented as being the original software. * * 3. This notice may not be removed or altered from any * source distribution. */ module dsfml.network.udpsocket; import dsfml.network.ipaddress; import dsfml.network.packet; import dsfml.network.socketstatus; import dsfml.system.common; /** * UdpSocket wraps a socket using UDP protocol to * send data fastly (but with less safety) */ class UdpSocket : DSFMLObject { /** * Default constructor */ this() { super(sfUdpSocket_Create()); m_intermediatePacket = new Packet(); } override void dispose() { sfUdpSocket_Destroy(m_ptr); } /** * 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) { m_port = port; return cast(bool)sfUdpSocket_Bind(m_ptr, port); } /** * Unbind the socket from its previous port, if any * * Returns: True if operation has been successful * */ bool unbind() { m_port = 0; return cast(bool)sfUdpSocket_Unbind(m_ptr, m_port); } /** * 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) { return cast(SocketStatus) sfUdpSocket_Send(m_ptr, data.ptr, data.length, address, port); } /** * 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) { SocketStatus ret = sfUdpSocket_Receive(m_ptr, data.ptr, data.length, &sizeReceived, &address); return ret; } /** * 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) { byte[] dataArray = packetToSend.onSend(); m_intermediatePacket.append(dataArray); SocketStatus stat = cast(SocketStatus)sfUdpSocket_SendPacket(m_ptr, m_intermediatePacket.nativePointer, address, port); m_intermediatePacket.clear(); return stat; } /** * 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) { SocketStatus ret = sfUdpSocket_ReceivePacket(m_ptr, m_intermediatePacket.nativePointer, &address); packetToReceive.onReceive(m_intermediatePacket.getData); m_intermediatePacket.clear(); return ret; } /** * 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() { return cast(bool)sfUdpSocket_IsValid(m_ptr); } /** * Get the port the socket is currently bound to * * Returns: * Current port (0 means the socket is not bound) */ ushort getPort() { return m_port; } package: this (SFMLClass ptr) { super(ptr); m_intermediatePacket = new Packet(); } private: Packet m_intermediatePacket; ushort m_port; // External ==================================================================== extern (C) { 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; 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; } static this() { debug DllLoader dll = DllLoader.load("csfml-network-d"); else DllLoader dll = DllLoader.load("csfml-network"); 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"); } }