socketConnectionPosix.cpp

00001 
00002 /* Copyright (c) 2005-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 using namespace eq::base;
00019 
00020 namespace eq
00021 {
00022 namespace net
00023 {
00024 SocketConnection::SocketConnection( const ConnectionType type )
00025 {
00026     EQASSERT( type == CONNECTIONTYPE_TCPIP || type == CONNECTIONTYPE_SDP );
00027     _description =  new ConnectionDescription;
00028     _description->type = type;
00029     _description->bandwidth = (type == CONNECTIONTYPE_TCPIP) ?
00030                                   102400 : 819200;
00031     EQVERB << "New SocketConnection @" << (void*)this << std::endl;
00032 }
00033 
00034 SocketConnection::~SocketConnection()
00035 {
00036     close();
00037 }
00038 
00039 //----------------------------------------------------------------------
00040 // connect
00041 //----------------------------------------------------------------------
00042 bool SocketConnection::connect()
00043 {
00044     EQASSERT( _description->type == CONNECTIONTYPE_TCPIP ||
00045               _description->type == CONNECTIONTYPE_SDP );
00046     if( _state != STATE_CLOSED )
00047         return false;
00048 
00049     if( _description->TCPIP.port == 0 )
00050         return false;
00051 
00052     _state = STATE_CONNECTING;
00053     _fireStateChanged();
00054 
00055     if( !_createSocket( ))
00056         return false;
00057 
00058     sockaddr_in socketAddress;
00059     if( !_parseAddress( socketAddress ))
00060     {
00061         EQWARN << "Can't parse connection parameters" << std::endl;
00062         close();
00063         return false;
00064     }
00065 
00066     if( socketAddress.sin_addr.s_addr == 0 )
00067     {
00068         EQWARN << "Refuse to connect to 0.0.0.0" << std::endl;
00069         close();
00070         return false;
00071     }
00072 
00073     const bool connected = (::connect( _readFD, (sockaddr*)&socketAddress, 
00074             sizeof(socketAddress)) == 0);
00075 
00076     if( !connected )
00077     {
00078         EQWARN << "Could not connect to '" << _description->getHostname() << ":"
00079              << _description->TCPIP.port << "': " << EQ_SOCKET_ERROR << std::endl;
00080         close();
00081         return false;
00082     }
00083  
00084     _state = STATE_CONNECTED;
00085     _fireStateChanged();
00086     return true;
00087 }
00088 
00089 void SocketConnection::close()
00090 {
00091     if( !(_state == STATE_CONNECTED || _state == STATE_LISTENING ))
00092         return;
00093 
00094     _state = STATE_CLOSED;
00095     EQASSERT( _readFD > 0 ); 
00096 
00097     const bool closed = ( ::close(_readFD) == 0 );
00098     if( !closed )
00099         EQWARN << "Could not close socket: " << EQ_SOCKET_ERROR << std::endl;
00100 
00101     _readFD  = INVALID_SOCKET;
00102     _writeFD = INVALID_SOCKET;
00103     _fireStateChanged();
00104 }
00105 
00106 //----------------------------------------------------------------------
00107 // Async IO handles
00108 //----------------------------------------------------------------------
00109 void SocketConnection::_initAIOAccept(){ /* NOP */ }
00110 void SocketConnection::_exitAIOAccept(){ /* NOP */ }
00111 void SocketConnection::_initAIORead(){ /* NOP */ }
00112 void SocketConnection::_exitAIORead(){ /* NOP */ }
00113 
00114 //----------------------------------------------------------------------
00115 // accept
00116 //----------------------------------------------------------------------
00117 void SocketConnection::acceptNB(){ /* NOP */ }
00118  
00119 ConnectionPtr SocketConnection::acceptSync()
00120 {
00121     if( _state != STATE_LISTENING )
00122         return 0;
00123 
00124     sockaddr_in newAddress;
00125     socklen_t   newAddressLen = sizeof( newAddress );
00126 
00127     Socket    fd;
00128     unsigned  nTries = 1000;
00129     do
00130         fd = ::accept( _readFD, (sockaddr*)&newAddress, &newAddressLen );
00131     while( fd == INVALID_SOCKET && errno == EINTR && --nTries );
00132 
00133     if( fd == INVALID_SOCKET )
00134     {
00135         EQWARN << "accept failed: " << EQ_SOCKET_ERROR << std::endl;
00136         return 0;
00137     }
00138 
00139     _tuneSocket( fd );
00140 
00141     SocketConnection* newConnection = new SocketConnection( _description->type);
00142 
00143     newConnection->_readFD      = fd;
00144     newConnection->_writeFD     = fd;
00145     newConnection->_state       = STATE_CONNECTED;
00146     newConnection->_description->bandwidth = _description->bandwidth;
00147     newConnection->_description->setHostname( inet_ntoa( newAddress.sin_addr ));
00148     newConnection->_description->TCPIP.port   = ntohs( newAddress.sin_port );
00149 
00150     EQVERB << "accepted connection from " << inet_ntoa(newAddress.sin_addr) 
00151            << ":" << ntohs( newAddress.sin_port ) << std::endl;
00152 
00153     return newConnection;
00154 }
00155 }
00156 }
Generated on Mon Aug 10 18:58:41 2009 for Equalizer 0.9 by  doxygen 1.5.8