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