|
1 /* |
|
2 oscpack -- Open Sound Control packet manipulation library |
|
3 http://www.audiomulch.com/~rossb/oscpack |
|
4 |
|
5 Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com> |
|
6 |
|
7 Permission is hereby granted, free of charge, to any person obtaining |
|
8 a copy of this software and associated documentation files |
|
9 (the "Software"), to deal in the Software without restriction, |
|
10 including without limitation the rights to use, copy, modify, merge, |
|
11 publish, distribute, sublicense, and/or sell copies of the Software, |
|
12 and to permit persons to whom the Software is furnished to do so, |
|
13 subject to the following conditions: |
|
14 |
|
15 The above copyright notice and this permission notice shall be |
|
16 included in all copies or substantial portions of the Software. |
|
17 |
|
18 Any person wishing to distribute modifications to the Software is |
|
19 requested to send the modifications to the original developer so that |
|
20 they can be incorporated into the canonical version. |
|
21 |
|
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
|
25 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR |
|
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
|
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
29 */ |
|
30 #ifndef INCLUDED_UDPSOCKET_H |
|
31 #define INCLUDED_UDPSOCKET_H |
|
32 |
|
33 #ifndef INCLUDED_NETWORKINGUTILITIES_H |
|
34 #include "NetworkingUtils.h" |
|
35 #endif /* INCLUDED_NETWORKINGUTILITIES_H */ |
|
36 |
|
37 #ifndef INCLUDED_IPENDPOINTNAME_H |
|
38 #include "IpEndpointName.h" |
|
39 #endif /* INCLUDED_IPENDPOINTNAME_H */ |
|
40 |
|
41 |
|
42 class PacketListener; |
|
43 class TimerListener; |
|
44 |
|
45 class UdpSocket; |
|
46 |
|
47 class SocketReceiveMultiplexer{ |
|
48 class Implementation; |
|
49 Implementation *impl_; |
|
50 |
|
51 friend class UdpSocket; |
|
52 |
|
53 public: |
|
54 SocketReceiveMultiplexer(); |
|
55 ~SocketReceiveMultiplexer(); |
|
56 |
|
57 // only call the attach/detach methods _before_ calling Run |
|
58 |
|
59 // only one listener per socket, each socket at most once |
|
60 void AttachSocketListener( UdpSocket *socket, PacketListener *listener ); |
|
61 void DetachSocketListener( UdpSocket *socket, PacketListener *listener ); |
|
62 |
|
63 void AttachPeriodicTimerListener( int periodMilliseconds, TimerListener *listener ); |
|
64 void AttachPeriodicTimerListener( |
|
65 int initialDelayMilliseconds, int periodMilliseconds, TimerListener *listener ); |
|
66 void DetachPeriodicTimerListener( TimerListener *listener ); |
|
67 |
|
68 void Run(); // loop and block processing messages indefinitely |
|
69 void RunUntilSigInt(); |
|
70 void Break(); // call this from a listener to exit once the listener returns |
|
71 void AsynchronousBreak(); // call this from another thread or signal handler to exit the Run() state |
|
72 }; |
|
73 |
|
74 |
|
75 class UdpSocket{ |
|
76 class Implementation; |
|
77 Implementation *impl_; |
|
78 |
|
79 friend class SocketReceiveMultiplexer::Implementation; |
|
80 |
|
81 public: |
|
82 |
|
83 // ctor throws std::runtime_error if there's a problem |
|
84 // initializing the socket. |
|
85 UdpSocket(); |
|
86 virtual ~UdpSocket(); |
|
87 |
|
88 // the socket is created in an unbound, unconnected state |
|
89 // such a socket can only be used to send to an arbitrary |
|
90 // address using SendTo(). To use Send() you need to first |
|
91 // connect to a remote endpoint using Connect(). To use |
|
92 // ReceiveFrom you need to first bind to a local endpoint |
|
93 // using Bind(). |
|
94 |
|
95 // retrieve the local endpoint name when sending to 'to' |
|
96 IpEndpointName LocalEndpointFor( const IpEndpointName& remoteEndpoint ) const; |
|
97 |
|
98 // Connect to a remote endpoint which is used as the target |
|
99 // for calls to Send() |
|
100 void Connect( const IpEndpointName& remoteEndpoint ); |
|
101 void Send( const char *data, int size ); |
|
102 void SendTo( const IpEndpointName& remoteEndpoint, const char *data, int size ); |
|
103 |
|
104 |
|
105 // Bind a local endpoint to receive incoming data. Endpoint |
|
106 // can be 'any' for the system to choose an endpoint |
|
107 void Bind( const IpEndpointName& localEndpoint ); |
|
108 bool IsBound() const; |
|
109 |
|
110 int ReceiveFrom( IpEndpointName& remoteEndpoint, char *data, int size ); |
|
111 }; |
|
112 |
|
113 |
|
114 // convenience classes for transmitting and receiving |
|
115 // they just call Connect and/or Bind in the ctor. |
|
116 // note that you can still use a receive socket |
|
117 // for transmitting etc |
|
118 |
|
119 class UdpTransmitSocket : public UdpSocket{ |
|
120 public: |
|
121 UdpTransmitSocket( const IpEndpointName& remoteEndpoint ) |
|
122 { Connect( remoteEndpoint ); } |
|
123 }; |
|
124 |
|
125 |
|
126 class UdpReceiveSocket : public UdpSocket{ |
|
127 public: |
|
128 UdpReceiveSocket( const IpEndpointName& localEndpoint ) |
|
129 { Bind( localEndpoint ); } |
|
130 }; |
|
131 |
|
132 |
|
133 // UdpListeningReceiveSocket provides a simple way to bind one listener |
|
134 // to a single socket without having to manually set up a SocketReceiveMultiplexer |
|
135 |
|
136 class UdpListeningReceiveSocket : public UdpSocket{ |
|
137 SocketReceiveMultiplexer mux_; |
|
138 PacketListener *listener_; |
|
139 public: |
|
140 UdpListeningReceiveSocket( const IpEndpointName& localEndpoint, PacketListener *listener ) |
|
141 : listener_( listener ) |
|
142 { |
|
143 Bind( localEndpoint ); |
|
144 mux_.AttachSocketListener( this, listener_ ); |
|
145 } |
|
146 |
|
147 ~UdpListeningReceiveSocket() |
|
148 { mux_.DetachSocketListener( this, listener_ ); } |
|
149 |
|
150 // see SocketReceiveMultiplexer above for the behaviour of these methods... |
|
151 void Run() { mux_.Run(); } |
|
152 void RunUntilSigInt() { mux_.RunUntilSigInt(); } |
|
153 void Break() { mux_.Break(); } |
|
154 void AsynchronousBreak() { mux_.AsynchronousBreak(); } |
|
155 }; |
|
156 |
|
157 |
|
158 #endif /* INCLUDED_UDPSOCKET_H */ |