fixed: auto_ptr -> unique_ptr
[opensg.git] / Doc / to_port / Socket.dox
blobf97055265eb9353e00f8a628701f765e5f53170b
1 #include <OSGConfig.h>
3 using namespace OSG;
5 /*! \page PageBaseSocket Socket
7 Socket baseclass. The Socket class wraps a socket descriptor. This
8 class has no additional state variables. It is only h handle to the
9 underlaying descriptor. Class createion and destruction has no
10 influence to any descriptor. Use open to assign a descriptor and
11 close to remove it from the system. If this class is copied, then
12 there are to classes which uses the same descriptor. This is
13 ok until you call close for one of this classes.
14 One purpose of this implementation is to hide the differences between
15 Windows and Unix sockets. Calls to this class should behave equally
16 on all systems. As a result, some methods will not work as an 
17 experienced Windows ore Unix programmer maight expect. Please refere
18 to the function docu to get details about this.
20 Stream sockets
22 A stream socket is an endpoint for a reliable point to point
23 communication. The following example code shows, how to establish a
24 stream socket connection.
26 <PRE>
27 // server code
28 StreamSocket socket,client;
29 socket.open();
30 socket.bind(SocketAddress(SocketAddress::ANY,12345));
31 client=socket.accept();
32 client.send(buffer,100);
33 client.close();
34 socket.close();
36 // client code
37 StreamSocket server;
38 server.open();
39 server.connect(SocketAddress("localhost",12345));
40 server.recv(buffer,100);
41 server.close();
42 </PRE>
44 The method bind() assigns the socket to a given port and network
45 device. If the network device is ANY, then the socket will accept
46 connections from all network interfaces. If the port number is zero,
47 then a free port is assigned. In the above example, the socket will
48 accept incoming connections at each interface on the port
49 12345. StreamSocket::accept() waits for a incoming connection. For
50 each incoming connection a new socket object will be created. With
51 send and recv data can be transferred over the connection. By default
52 all calls will block until the operation has finished.
54 Datagram sockets
56 Datagram sockets are not connection orientated. There is no connect or
57 accept methods for datagram sockets. You have to provide a destination
58 address for each send and will get a source address for each recv
59 call. There is no guarantee that packages will arrive and there is no
60 guarantee for the order in which the package will arrive. The followin
61 code shows how to wait for incoming packages at port 22222. 
63 <PRE>
64 SocketAddress client;
65 DgramSocket socket;
66 socket.open();
67 socket.bind(SocketAddress(SocketAddress::ANY,22222))
68 socket.recvFrom(buffer,100,client);
69 socket.close();
70 </PRE>
72 This is the code to send the package. This is a simple example. If the
73 package gets lost for example because the server is not started, then
74 this code wont work. If your application relays on reliable data
75 transmission, then StreamSockets should be used. 
77 <PRE>
78 DgramSocket sock;
79 SocketAddress server;
80 socket.open();
81 socket.sendTo("hallo",100,SocketAddress("localhost",22222));
82 socket.close();
83 </PRE>
85 Exceptions:
87 All socket methods will throw exceptions if the desired function could
88 not be finished. All socket related exceptions are derived from the
89 SocketException class. All socket calls should be enclosed in
90 try/catch blocks. For example, if you want to check if a connect
91 operation was successful then you should use the following code.
93 <PRE>
94 try
96     server..connect(SocketAddress("localhost",12345));
98 catch(SocketException &e)
100     SFATAL << "Unable to connect to server:" << e.what() << endl;
102 </PRE>
104 Each exceptions contains the system error text that causes the error
105 situation. This text can be accessed by SocketException::what(). The
106 text is given as an std:string object.
108 Broadcast Messages
110 Broadcast packages are a special case of datagram packages. Broadcast
111 packages are send to each host in a network. For broadcasting packages
112 a special address type is used. For example with the address
113 SocketAddress(SocketAddress::BROADCAST,2345) packages will be send to each
114 host on port number 2345. Equal to normal datagram sockets, broadcast
115 packages are transmitted not reliable. 
117 Multicast Messages
119 With multicast it is possible to send packages to more then one
120 destination. In contrast to broadcast the package is not send to all
121 hosts but only to those hosts that have joined a multicast group. A
122 multicast group is specified with special IP addresses
123 (224.xxx.xxx.xxx). To write a package to the multicast group
124 224.22.33.33 at port 4444 you could use
126 <PRE>
127 socket.sendTo(buffer,100,SocketAddress("224.22.33.44",4444) 
128 </PRE>
130 The receive has to join this group. The following examples shows how
131 to join and leave multicast groups. It is possible to join more then
132 one group.
134 <PRE>
135 socket.bind(SocketAddress(SocketAddress::ANY,4444));
136 socket.join(SocketAddress("224.22.33.44"));
137 socket.join(SocketAddress("224.0.0.52"));
138 socket.join(SocketAddress("224.0.0.53"));
139 socket.leave(SocketAddress("224.0.0.52"));
140 </PRE>
142 With multicast groups you also have to bind your socket to a network
143 device and port. In the example above only those packages are received
144 that are send to port 4444. With multicast it often happens, that you
145 have more then one member of a multicast group on a single host. If
146 you try to call bind for the same port multiple times, then you will
147 get socket exceptions. To be able to assign more then one process to
148 the same port you have to call  socket.setReusePort(true) before the
149 call to bind.
151 It is possible set the network device that is used to send 
152 multicast packages. By default the system uses the first device
153 that is capable to send multicast packages.
155 <PRE>
156 socket.setInterface(SocketAddress("192.168.10.1"));
157 </PRE>
159 Nonblocking IO
161 In many applications it is not possible or not wanted to block
162 execution until an accept() or recv() call has finished. Each socket
163 has methods to ask if it is possible to read or write data without
164 blocking. The followin examples shows how to wait for data without
165 blocking.
167 <UL>
168 <LI>socket.waitReadable(0): Don't wait, returns true if data is
169 available otherwise it returns false.
170 <LI>socket.waitReadable(0.5): If data arrives in the next .5 seconds
171 then true is returned. Otherwise false is returned.
172 <LI>socket.waitReadable(-1): Wait until data is available and then
173 return true. This function call is equal to a blocking read.
174 <LI>socket.waitWritable(10): If the socket is able to send data in the
175 next 10 seconds, then true is returned. Otherwise false. 
176 </UL>
178 With this simple interface it is possible to wait a specified time for
179 incoming or outgoing data. But it is only possible to wait for exactly one
180 socket. If it is necessary to wait for more then one socket then the
181 Selection class could be used.  A selection specifies for each socket
182 for what kind of event the system should wait. 
184 <PRE>
185 SocketSelection s;
186 s.setRead(socket1);
187 s.setRead(socket2);
188 s.select(.1);
189 if(s.isSetRead(sock1)) 
190    socket 1 is readable
191 if(s.isSetRead(sock2)) 
192    socket 1 is readable
193 </PRE>
195 A call of selection.select(seconds) waits the given number of seconds for the events set with setRead() or serWrite(). It returns after the first occurrence of an event.  If no events occur in the given periode then 0 is returned. Otherwise the number of readable and writable sockets is returned. The method select() modifies the selection object. You have to call setRead() and setWrite() for each time, you want to call select(). If the SocketSelection is constant, then you can use an other version of select. With s.select(seconds,rs) s will not be modified. The result will be set into the SocketSelection rs. You have to call rs.isReadable(sock) instead of s.isReadable(sock).
197 IO-Buffers
199 If data should be read from more then one socket, then the performance could be improved by not reading from the first socket that provides data but from that socket with the most data in the input buffer. With socket.getAvailable() the number of bytes in the input buffer could be retrieved. In addition the Socket class provides the functions setWriteBufferSize and setReadBufferSize set the size of input and output buffers. Current sizes can be retrieved with getReadBufferSize and getWriteBufferSize.