1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
48 #include "OSGSocketSelection.h"
49 #include "OSGPointSockConnection.h"
50 #include "OSGGroupSockConnection.h"
51 #include "OSGConnectionType.h"
55 /** \class OSG::PointSockConnection
58 /*-------------------------------------------------------------------------*/
59 /* constructor destructor */
64 PointSockConnection::PointSockConnection():
69 _socketReadBuffer ( ),
73 _acceptSocket
.setReusePort(true);
75 _socketReadBuffer
.resize(131071);
76 _socketWriteBuffer
.resize( _socketReadBuffer
.size() );
77 // reserve first bytes for buffer size
78 readBufAdd (&_socketReadBuffer
[sizeof(SocketBufferHeader
)],
79 _socketReadBuffer
.size() -sizeof(SocketBufferHeader
));
80 writeBufAdd(&_socketWriteBuffer
[sizeof(SocketBufferHeader
)],
81 _socketWriteBuffer
.size()-sizeof(SocketBufferHeader
));
86 PointSockConnection::~PointSockConnection(void)
88 _acceptSocket
.close();
91 /*! get connection type
93 const ConnectionType
*PointSockConnection::getType()
98 /*-------------------------------------------------------------------------*/
101 /*! connect to the given point. If timeout is reached, -1 is
104 Connection::Channel
PointSockConnection::connectPoint(
105 const std::string
&address
,
109 if(GroupSockConnection::connectSocket( socket
,
115 _pointToPoint
= true;
124 /*! connect to the given group. If timeout is reached, -1 is
127 Connection::Channel
PointSockConnection::connectGroup(
128 const std::string
&address
,
132 if(GroupSockConnection::connectSocket( socket
,
138 _pointToPoint
= false;
147 /*! disconnect the given channel
149 void PointSockConnection::disconnect(void)
154 /*! accept an icomming point connection. If timeout is reached,
155 -1 is returned. If timeout is -1 then wait without timeout
157 Connection::Channel
PointSockConnection::acceptPoint(Time timeout
)
159 if(GroupSockConnection::acceptSocket(_acceptSocket
,
164 _pointToPoint
= true;
173 /*! accept an icomming grop connection. If timeout is reached,
174 -1 is returned. If timeout is -1 then wait without timeout
176 Connection::Channel
PointSockConnection::acceptGroup(Time timeout
)
178 if(GroupSockConnection::acceptSocket(_acceptSocket
,
183 _pointToPoint
= false;
192 /*! bind the connection to a network interface. The address is
193 returned, on wich the port could be connected. The interface
194 is determined by the connection interface filed and the
195 address parameter. Address can be empty, wich means to use
196 a free port or address can contain a port number.
198 std::string
PointSockConnection::bind(const std::string
&address
)
205 // get local host name
206 osgGetHostname(localhost
,255);
207 if(!getInterface().empty())
208 interf
= getInterface();
214 if(sscanf(address
.c_str(),"%*[^:]:%d",&port
) != 1)
215 if(sscanf(address
.c_str(),":%d",&port
) != 1)
218 _acceptSocket
.setReusePort(true);
219 if(!getInterface().empty())
220 _acceptSocket
.bind(SocketAddress(getInterface().c_str(),port
));
222 _acceptSocket
.bind(SocketAddress(SocketAddress::ANY
,port
));
224 SINFO
<< "Connection bound to "
225 << _acceptSocket
.getAddress().getHost() << ":"
226 << _acceptSocket
.getAddress().getPort() << std::endl
;
227 _acceptSocket
.listen();
229 sprintf(portStr
,"%d",_acceptSocket
.getAddress().getPort());
230 return interf
+ ":" + portStr
;
233 /*-------------------------------------------------------------------------*/
234 /* channel handling */
236 /*! select the next channel for reading. If timeout is not -1
237 then -1 is returned if timeout is reached
239 Connection::Channel
PointSockConnection::selectChannel(Time timeout
)
240 OSG_THROW (ReadError
)
244 if(_socket
.waitReadable(timeout
))
247 catch(SocketError
&e
)
249 throw ReadError(e
.what());
254 /*-------------------------------------------------------------------------*/
259 bool PointSockConnection::wait(Time timeout
) OSG_THROW (ReadError
)
264 if(!_socket
.waitReadable(timeout
))
266 if(!_socket
.recv(&tag
,sizeof(tag
)))
267 throw ReadError("Channel closed");
269 tag
= osgNetToHost
<UInt32
>(tag
);
272 FFATAL(("Stream out of sync in SockConnection\n"));
273 throw ReadError("Stream out of sync");
276 catch(SocketError
&e
)
278 throw ReadError(e
.what());
285 void PointSockConnection::signal(void) OSG_THROW (WriteError
)
287 UInt32 tag
= osgHostToNet
<UInt32
>(314156);
290 _socket
.send(&tag
,sizeof(tag
));
292 catch(SocketError
&e
)
294 throw WriteError(e
.what());
298 /*-------------------------- create ---------------------------------------*/
300 /** \brief create conneciton
303 PointConnection
*PointSockConnection::create(void)
305 return new PointSockConnection();
308 /*-------------------------------------------------------------------------*/
311 /** Read data into given memory
313 * Read data form the current read socket. The read socket is that
314 * socket, that was selectet in selectChannel.
318 void PointSockConnection::read(MemoryHandle mem
,UInt32 size
)
323 len
=_socket
.recv(mem
,size
);
326 throw ReadError("read got 0 bytes!");
330 /** Read next data block
332 * The stream connection uses only BinaryDataHandler buffer. If more
333 * then one buffer is present, then this methode must be changed!
337 void PointSockConnection::readBuffer() OSG_THROW (ReadError
)
342 // read buffer header
343 len
=_socket
.recv(&_socketReadBuffer
[0],sizeof(SocketBufferHeader
));
345 throw ReadError("peek got 0 bytes!");
346 // read remaining data
347 size
=osgNetToHost
<UInt32
>((reinterpret_cast<SocketBufferHeader
*>(&_socketReadBuffer
[0]))->size
);
348 len
=_socket
.recv(&_socketReadBuffer
[sizeof(SocketBufferHeader
)],
351 throw ReadError("read got 0 bytes!");
352 readBufBegin()->setDataSize(size
);
355 /** Write data to destinations
357 * \param mem Pointer to data buffer
358 * \param size Size of bytes to write
362 void PointSockConnection::write(MemoryHandle mem
,UInt32 size
)
364 _socket
.send(mem
,size
);
369 * Write blocksize and data.
372 void PointSockConnection::writeBuffer(void)
374 UInt32 size
= writeBufBegin()->getDataSize();
376 // write size to header
377 (reinterpret_cast<SocketBufferHeader
*>(&_socketWriteBuffer
[0]))->size
=
378 osgHostToNet
<UInt32
>(size
);
383 _socket
.send(&_socketWriteBuffer
[0],
384 size
+sizeof(SocketBufferHeader
));
388 /*-------------------------------------------------------------------------*/
391 ConnectionType
PointSockConnection::_type(
392 &PointSockConnection::create
,