// caller: application bool UDTConnection::tuneSocket( ) { const int timeout = (int)Global::getTimeout( ); /* TODO: Use our own Globals? const int udt_snd_buf = 10240000; const int udt_rcv_buf = 10240000; const int udp_snd_buf = Global::getIAttribute( Global::IATTR_UDP_BUFFER_SIZE ); const int udp_rcv_buf = Global::getIAttribute( Global::IATTR_UDP_BUFFER_SIZE ); */ const int mss = 65520;//Global::getIAttribute( Global::IATTR_UDP_MTU ); if( !setSockOpt( UDT_SNDTIMEO, static_cast<const void *>( &timeout ), sizeof(timeout) )) goto err; if( !setSockOpt( UDT_RCVTIMEO, static_cast<const void *>( &timeout ), sizeof(timeout) )) goto err; /* if( !setSockOpt( UDT_SNDBUF, static_cast<const void *>( &udt_snd_buf ), sizeof(udt_snd_buf) )) goto err; if( !setSockOpt( UDT_RCVBUF, static_cast<const void *>( &udt_rcv_buf ), sizeof(udt_rcv_buf) )) goto err; if( !setSockOpt( UDP_SNDBUF, static_cast<const void *>( &udp_snd_buf ), sizeof(udp_snd_buf) )) goto err; if( !setSockOpt( UDP_RCVBUF, static_cast<const void *>( &udp_rcv_buf ), sizeof(udp_rcv_buf) )) goto err; */ if( !setSockOpt( UDT_MSS, static_cast<const void *>( &mss ), sizeof(mss) )) goto err; #ifdef CONGESTION_CONTROL_CLASS if( !setSockOpt( UDT_CC, static_cast<const void *>( new CCCFactory<CONGESTION_CONTROL_CLASS> ), sizeof(CCCFactory<CONGESTION_CONTROL_CLASS>) )) goto err; #endif return true; err: return false; }
// caller: application bool UDTConnection::connect( ) { struct sockaddr address; CCC *cc = NULL; int len; ConstConnectionDescriptionPtr description = getDescription(); LBASSERT( CONNECTIONTYPE_UDT == description->type ); if( !isClosed( )) return false; _setState( STATE_CONNECTING ); if( !_parseAddress( description, address, false )) goto err; LBASSERT( UDT::INVALID_SOCK == _udt ); _udt = UDT::socket( AF_INET, SOCK_STREAM, 0 ); if( UDT::INVALID_SOCK == _udt ) { LBERROR << UDTLASTERROR( "UDT::socket" ) << std::endl; goto err; } if( !tuneSocket( )) goto err; if( UDT::ERROR == UDT::connect( _udt, &address, sizeof( address ))) { LBERROR << UDTLASTERROR( "UDT::connect" ) << std::endl; goto err; } // Do this after connect, otherwise connect itself becomes non-blocking static const bool OFF = false; if( !setSockOpt( UDT_RCVSYN, static_cast<const void *>( &OFF ), sizeof(OFF) )) goto err; if( UDT::ERROR != UDT::getsockopt( _udt, 0, UDT_CC, &cc, &len )) { if( NULL != cc ) { CUDPBlast *ccblast = dynamic_cast<CUDPBlast *>( cc ); if( NULL != ccblast ) ccblast->setRate( description->bandwidth / 1000. ); } } if( initialize( )) { _setState( STATE_CONNECTED ); return true; } err: return false; }
int CSocket::setReuse(bool bReuse) { int iReuseAddr = 0; if(bReuse){ iReuseAddr = 1; } return setSockOpt(SO_REUSEADDR, (const void *)&iReuseAddr, sizeof(int), SOL_SOCKET); }
bool Socket::init(const char *ip, unsigned int port, int type, bool block) { int optval = 1; struct sockaddr_in addr; socklen_t addrLen; if ( (this->fd = socket(AF_INET, type, 0)) == -1 ) { KY_LOG_ERROR("socket error, errno(%d)", errno); return false; } // SO_REUSEADDR 允许在bind()过程中本地地址可重复使用 if ( !setSockOpt(this->fd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval)) ) { return false; } if ( block == false ) { if ( this->setNonblock() == false ) { return false; } } Socket::initSockAddr( addr, ip, port ); if( bind(this->fd, (struct sockaddr *)&addr, sizeof(addr)) == -1 ) { KY_LOG_ERROR("bind error, errno(%d)", errno); return false; } if ( port == SOCKET_PORT_ANY ) { addrLen = sizeof(addr); // 如果端口为ANY,则获取系统所分配的端口 getsockname(this->fd, (struct sockaddr *)&(addr), &addrLen); } //snprintf(this->ip, "%s", ip); this->saveLocal( addr ); return true; }