std::unique_ptr<TCPStream> TCPConnector::connect(const char* server, int port, int timeout) { if (timeout == 0) return connect(server, port); struct sockaddr_in address; std::memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(port); if (ResolveHostName(server, &(address.sin_addr)) != 0) { inet_pton(PF_INET, server, &(address.sin_addr)); } long arg; fd_set sdset; struct timeval tv; socklen_t len; int result = -1, valopt, sd = socket(AF_INET, SOCK_STREAM, 0); // Set socket to non-blocking arg = fcntl(sd, F_GETFL, nullptr); arg |= O_NONBLOCK; fcntl(sd, F_SETFL, arg); // Connect with time limit std::string message; if ((result = ::connect(sd, (struct sockaddr*)&address, sizeof(address))) < 0) { if (errno == EINPROGRESS) { tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&sdset); FD_SET(sd, &sdset); if (select(sd + 1, nullptr, &sdset, nullptr, &tv) > 0) { len = sizeof(int); getsockopt(sd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &len); if (valopt) { fprintf(stderr, "connect() error %d - %s\n", valopt, strerror(valopt)); } // connection established else result = 0; } else fprintf(stderr, "connect() timed out\n"); } else fprintf(stderr, "connect() error %d - %s\n", errno, strerror(errno)); } // Return socket to blocking mode arg = fcntl(sd, F_GETFL, nullptr); arg &= (~O_NONBLOCK); fcntl(sd, F_SETFL, arg); // Create stream object if connected if (result == -1) return nullptr; return std::unique_ptr<TCPStream>(new TCPStream(sd, &address)); }
///////////////////////////////////////////////////////////////////// // GetIPAddress (a helper function) ///////////////////////////////////////////////////////////////////// DWORD __stdcall GetIPAddress( LPSTR lpszIPAddress, LPDWORD lpdwIPAddressSize ) { char szHostBuffer[255]; if( gethostname( szHostBuffer, sizeof(szHostBuffer) - 1 ) != ERROR_SUCCESS ) return( ERROR_INTERNET_INTERNAL_ERROR ); return( ResolveHostName( szHostBuffer, lpszIPAddress, lpdwIPAddressSize ) ); }
///////////////////////////////////////////////////////////////////// // IsResolvable (a helper function) ///////////////////////////////////////////////////////////////////// BOOL __stdcall IsResolvable( LPSTR lpszHost ) { char szDummy[255]; DWORD dwDummySize = sizeof(szDummy) - 1; if( ResolveHostName( lpszHost, szDummy, &dwDummySize ) ) return( FALSE ); return TRUE; }
std::unique_ptr<TCPStream> TCPConnector::connect(const char* server, int port) { struct sockaddr_in address; std::memset(&address, 0, sizeof(address)); address.sin_family = AF_INET; address.sin_port = htons(port); if (ResolveHostName(server, &(address.sin_addr)) != 0) { inet_pton(PF_INET, server, &(address.sin_addr)); } int sd = socket(AF_INET, SOCK_STREAM, 0); if (::connect(sd, (struct sockaddr*)&address, sizeof(address)) != 0) { perror("connect() failed"); return nullptr; } return std::unique_ptr<TCPStream>(new TCPStream(sd, &address)); }
LiveAppModuleImpl::LiveAppModuleImpl(const LiveAppModuleCreateParam& param, const TCHAR* tagname, bool tagMutate) : m_CreateParam( param ), m_NormalUDPSender(param.NormalUDPSender), m_TCPProxyUDPSender(param.TCPProxyUDPSender), m_HTTPProxyUDPSender(param.HTTPProxyUDPSender), m_AutoMaxAppPeerCount(20), m_AutoMinAppPeerCount(0), m_BootModule( new BootModule(param.NormalUDPSender) ) { TEST_LOG_OPEN( paths::combine( param.ConfigDirectory, _T("live_test.log") ).c_str() ); m_SysInfo = static_cast<const CSysInfo*>(param.SysInfo); m_PeerInformation.reset(new PeerInformation(param.ChannelGUID, param.SysInfo->PeerGUID, param.AppVersion, param.AppVersionNumber16, CreatePeerNetInfo(*m_SysInfo))); m_PeerInformation->NetInfo->CoreInfo.PeerType = param.PeerType; LIVE_ASSERT(m_SysInfo != NULL); m_PeerCountLimit = m_SysInfo->MaxAppPeerCount; LIMIT_MIN(m_PeerCountLimit, PPL_MIN_PEER_COUNT_LIMIT); // 传入的最大peer个数应该不超过一个最大限制PPL_MAX_PEER_COUNT_LIMIT LIVE_ASSERT(m_PeerCountLimit <= PPL_MAX_PEER_COUNT_LIMIT); LIMIT_MAX(m_PeerCountLimit, PPL_MAX_PEER_COUNT_LIMIT); m_iptable.Load(m_CreateParam.BaseDirectory); boost::shared_ptr<IDGenerator> trackerTransactionID(new IDGenerator()); boost::shared_ptr<IDGenerator> peerTransactionID(new IDGenerator()); m_UDPConnectionlessPacketBuilder.reset(new UDPConnectionlessPacketBuilder(peerTransactionID)); m_TCPConnectionlessPacketBuilder.reset(new TCPConnectionlessPacketBuilder()); m_OldTrackerPacketBuilder.reset(new UDPPacketBuilder(trackerTransactionID)); // 用于tracker报文 m_SecureUDPPacketBuilder.reset( new SecureTrackerRequestPacketBuilder( trackerTransactionID ) ); boost::shared_ptr<UDPConnectionPacketBuilder> udpConnectionPacketBuilder(new UDPConnectionPacketBuilder(peerTransactionID)); boost::shared_ptr<TCPConnectionPacketBuilder> tcpPacketBuilder(new TCPConnectionPacketBuilder()); m_SecureTrackerProxyPacketBuilder.reset( new SecureTrackerProxyPacketBuilder( trackerTransactionID ) ); m_SecureTrackerProxyPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID ); m_OldTrackerPacketBuilder->InitHeadInfo( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID ); m_SecureUDPPacketBuilder->Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, m_PeerInformation->NetInfo->CoreInfo, m_PeerInformation->AppVersion ); m_UDPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, *m_PeerInformation->NetInfo, m_PeerInformation->AppVersion); m_TCPConnectionlessPacketBuilder->PeerInfo.Init( m_PeerInformation->ChannelGUID, m_PeerInformation->PeerGUID, *m_PeerInformation->NetInfo, m_PeerInformation->AppVersion); m_UDPPacketSender.reset(new TrackerPacketSender(m_OldTrackerPacketBuilder, m_SecureUDPPacketBuilder, m_NormalUDPSender, m_TCPProxyUDPSender, m_HTTPProxyUDPSender, m_PeerInformation, m_Statistics.OldUDPFlow.Upload, m_Statistics.TotalFlow.Upload)); m_UDPConnectionlessPacketSender.reset( new UDPConnectionlessPacketSender( m_UDPConnectionlessPacketBuilder, m_NormalUDPSender, m_PeerInformation, m_Statistics.UDPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_UDPConnectionPacketSender.reset( new UDPConnectionPacketSender( udpConnectionPacketBuilder, m_NormalUDPSender, m_Statistics.UDPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_TCPConnectionlessPacketSender.reset( new TCPConnectionlessPacketSender( m_TCPConnectionlessPacketBuilder, m_PeerInformation, m_Statistics.TCPConnectionlessFlow.Upload, m_Statistics.TotalFlow.Upload ) ); m_TCPConnectionPacketSender.reset( new TCPConnectionPacketSender( tcpPacketBuilder, m_Statistics.TCPConnectionFlow.Upload, m_Statistics.TotalFlow.Upload ) ); VIEW_ERROR("Create New AppModule! " << this << " ResourceGUID=" << param.ChannelGUID); m_LiveInfo = CreateLiveInfo(m_StatisticsInfo, m_MappingLiveInfo, tagname, m_PeerCountLimit, param, m_PeerInformation->AppVersion, tagMutate); LoadTracker(param.Trackers); InitPeerAuthInfo(*m_PeerInformation->AuthInfo, param); { //#if defined(_PPL_PLATFORM_LINUX) || defined(_PPL_USE_ASIO) // ini_file ini; // this->InitIni(ini); // ini.set_section(_T("media")); // int netWriterMode = ini.get_int(_T("NetWriterMode"), 0); // m_mediaServerListener.reset(CreateMediaServerListener(netWriterMode)); //#elif defined(_PPL_PLATFORM_MSWIN) m_mediaServerListener.reset(CreateMediaServerListener(*m_LiveInfo)); //#endif } /* ----------Removed by Tady, 04142010: Moved into Func. Start(). if ( NORMAL_PEER == param.PeerType ) { // 检查stun type MY_STUN_NAT_TYPE natType = this->LoadNATType(); if ( STUN_TYPE_INVALID == natType ) { // 读取nat类型失败,另起线程检测 m_StunTypeResolver.reset( new StunTypeResolver ); m_StunTypeResolver->Resolve(StunTypeResolver::CallbackType(boost::bind(&LiveAppModuleImpl::OnNATQuerySucceeded, this, _1))); } else { // 保存nat类型到NetInfo对象 m_PeerInformation->NetInfo->SetNATType( natType ); m_LiveInfo->LocalPeerInfo.NetInfo.CoreInfo.NATType = natType; } } */ { std::vector<InetSocketAddress> stunServers; ini_file ini; this->InitConfig(ini); ini.set_section(_T("stun")); tstring serverListStr = ini.get_string(_T("servers"), _T("")); int day = ini.get_int(_T("time"), -1); SYSTEMTIME st; GetLocalTime(&st); if ( false == serverListStr.empty() && ( day > 0 ) && (abs(st.wDay - day) < 3) ) { std::vector<tstring> serverList; strings::split(std::back_inserter(serverList), serverListStr, _T('|')); for ( size_t serverIndex = 0; serverIndex < serverList.size(); ++serverIndex ) { pair<tstring, tstring> ipAndPort = strings::split_pair(serverList[serverIndex], _T(':')); if ( false == ipAndPort.first.empty() && false == ipAndPort.second.empty() ) { UINT ip = ResolveHostName(ipAndPort.first); WORD port = static_cast<WORD>( _ttoi(ipAndPort.second.c_str()) ); if ( ip != 0 && ip != INADDR_NONE && port != 0) { stunServers.push_back(InetSocketAddress(ip, port)); } } } } if ( false == stunServers.empty() ) { this->StartStunModule(stunServers); } else { // 向boot server查询 m_BootModule->QueryNTSList(BootModule::NTSListCallbackType(boost::bind(&LiveAppModuleImpl::OnNTSListOK, this, _1))); } } m_LogClient.reset( new LogClient( m_CreateParam.BaseDirectory, m_CreateParam.ConfigDirectory, m_PeerInformation ) ); m_timer.set_callback(boost::bind(&LiveAppModuleImpl::OnAppTimer, this)); //#ifdef _DEBUG #ifdef _PPL_PLATFORM_MSWIN #pragma message("!!!!!!从params.ini中加载TransferMethod设置") #endif { ini_file ini; this->InitIni(ini); ini.set_section(_T("connector")); int method = ini.get_int(_T("TransferMethod"), 0); VIEW_DEBUG("Load TransferMethod " << method); if (method != TRANSFER_ALL && method != TRANSFER_UDP && method != TRANSFER_TCP && method != TRANSFER_NO_DETECT) { method = TRANSFER_ALL; } m_LiveInfo->TransferMethod = (BYTE)method; } //#endif TEST_LOG_OUT("live start"); TEST_LOG_OUT("channel id " << param.ChannelGUID); TEST_LOG_OUT("peer id " << param.SysInfo->PeerGUID); TEST_LOG_OUT("peer address " << m_PeerInformation->NetInfo->Address); TEST_LOG_FLUSH(); }
virtual void DoRun() { UINT ip = ResolveHostName( "0.1.0.4" ); LIVE_ASSERT( false == CheckIPValid( ip ) ); LIVE_ASSERT( false == CheckIPFullyValid( ip ) ); }