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 }
0.9 by
1.5.8