andrew@0: /* andrew@0: oscpack -- Open Sound Control packet manipulation library andrew@0: http://www.audiomulch.com/~rossb/oscpack andrew@0: andrew@0: Copyright (c) 2004-2005 Ross Bencina andrew@0: andrew@0: Permission is hereby granted, free of charge, to any person obtaining andrew@0: a copy of this software and associated documentation files andrew@0: (the "Software"), to deal in the Software without restriction, andrew@0: including without limitation the rights to use, copy, modify, merge, andrew@0: publish, distribute, sublicense, and/or sell copies of the Software, andrew@0: and to permit persons to whom the Software is furnished to do so, andrew@0: subject to the following conditions: andrew@0: andrew@0: The above copyright notice and this permission notice shall be andrew@0: included in all copies or substantial portions of the Software. andrew@0: andrew@0: Any person wishing to distribute modifications to the Software is andrew@0: requested to send the modifications to the original developer so that andrew@0: they can be incorporated into the canonical version. andrew@0: andrew@0: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, andrew@0: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF andrew@0: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. andrew@0: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR andrew@0: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF andrew@0: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION andrew@0: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. andrew@0: */ andrew@0: #ifndef INCLUDED_UDPSOCKET_H andrew@0: #define INCLUDED_UDPSOCKET_H andrew@0: andrew@0: #ifndef INCLUDED_NETWORKINGUTILITIES_H andrew@0: #include "NetworkingUtils.h" andrew@0: #endif /* INCLUDED_NETWORKINGUTILITIES_H */ andrew@0: andrew@0: #ifndef INCLUDED_IPENDPOINTNAME_H andrew@0: #include "IpEndpointName.h" andrew@0: #endif /* INCLUDED_IPENDPOINTNAME_H */ andrew@0: andrew@0: andrew@0: class PacketListener; andrew@0: class TimerListener; andrew@0: andrew@0: class UdpSocket; andrew@0: andrew@0: class SocketReceiveMultiplexer{ andrew@0: class Implementation; andrew@0: Implementation *impl_; andrew@0: andrew@0: friend class UdpSocket; andrew@0: andrew@0: public: andrew@0: SocketReceiveMultiplexer(); andrew@0: ~SocketReceiveMultiplexer(); andrew@0: andrew@0: // only call the attach/detach methods _before_ calling Run andrew@0: andrew@0: // only one listener per socket, each socket at most once andrew@0: void AttachSocketListener( UdpSocket *socket, PacketListener *listener ); andrew@0: void DetachSocketListener( UdpSocket *socket, PacketListener *listener ); andrew@0: andrew@0: void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ); andrew@0: void AttachPeriodicTimerListener( andrew@0: int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ); andrew@0: void DetachPeriodicTimerListener( TimerListener *listener ); andrew@0: andrew@0: void Run(); // loop and block processing messages indefinitely andrew@0: void RunUntilSigInt(); andrew@0: void Break(); // call this from a listener to exit once the listener returns andrew@0: void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state andrew@0: }; andrew@0: andrew@0: andrew@0: class UdpSocket{ andrew@0: class Implementation; andrew@0: Implementation *impl_; andrew@0: andrew@0: friend class SocketReceiveMultiplexer::Implementation; andrew@0: andrew@0: public: andrew@0: andrew@0: // ctor throws std::runtime_error if there's a problem andrew@0: // initializing the socket. andrew@0: UdpSocket(); andrew@0: virtual ~UdpSocket(); andrew@0: andrew@0: // the socket is created in an unbound, unconnected state andrew@0: // such a socket can only be used to send to an arbitrary andrew@0: // address using SendTo(). To use Send() you need to first andrew@0: // connect to a remote endpoint using Connect(). To use andrew@0: // ReceiveFrom you need to first bind to a local endpoint andrew@0: // using Bind(). andrew@0: andrew@0: // retrieve the local endpoint name when sending to 'to' andrew@0: IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const; andrew@0: andrew@0: // Connect to a remote endpoint which is used as the target andrew@0: // for calls to Send() andrew@0: void Connect( const IpEndpointName& remoteEndpoint ); andrew@0: void Send( const char *data, int size ); andrew@0: void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size ); andrew@0: andrew@0: andrew@0: // Bind a local endpoint to receive incoming data. Endpoint andrew@0: // can be 'any' for the system to choose an endpoint andrew@0: void Bind( const IpEndpointName& localEndpoint ); andrew@0: bool IsBound() const; andrew@0: andrew@0: int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size ); andrew@0: }; andrew@0: andrew@0: andrew@0: // convenience classes for transmitting and receiving andrew@0: // they just call Connect and/or Bind in the ctor. andrew@0: // note that you can still use a receive socket andrew@0: // for transmitting etc andrew@0: andrew@0: class UdpTransmitSocket : public UdpSocket{ andrew@0: public: andrew@0: UdpTransmitSocket( const IpEndpointName& remoteEndpoint ) andrew@0: { Connect( remoteEndpoint ); } andrew@0: }; andrew@0: andrew@0: andrew@0: class UdpReceiveSocket : public UdpSocket{ andrew@0: public: andrew@0: UdpReceiveSocket( const IpEndpointName& localEndpoint ) andrew@0: { Bind( localEndpoint ); } andrew@0: }; andrew@0: andrew@0: andrew@0: // UdpListeningReceiveSocket provides a simple way to bind one listener andrew@0: // to a single socket without having to manually set up a SocketReceiveMultiplexer andrew@0: andrew@0: class UdpListeningReceiveSocket : public UdpSocket{ andrew@0: SocketReceiveMultiplexer mux_; andrew@0: PacketListener *listener_; andrew@0: public: andrew@0: UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener ) andrew@0: : listener_( listener ) andrew@0: { andrew@0: Bind( localEndpoint ); andrew@0: mux_.AttachSocketListener( this, listener_ ); andrew@0: } andrew@0: andrew@0: ~UdpListeningReceiveSocket() andrew@0: { mux_.DetachSocketListener( this, listener_ ); } andrew@0: andrew@0: // see SocketReceiveMultiplexer above for the behaviour of these methods... andrew@0: void Run() { mux_.Run(); } andrew@0: void RunUntilSigInt() { mux_.RunUntilSigInt(); } andrew@0: void Break() { mux_.Break(); } andrew@0: void AsynchronousBreak() { mux_.AsynchronousBreak(); } andrew@0: }; andrew@0: andrew@0: andrew@0: #endif /* INCLUDED_UDPSOCKET_H */