wxString CTransferSocket::SetupActiveTransfer(const wxString& ip) { ResetSocket(); m_pSocketServer = CreateSocketServer(); if (!m_pSocketServer) { m_pControlSocket->LogMessage(::Debug_Warning, _T("CreateSocketServer failed")); return _T(""); } int error; int port = m_pSocketServer->GetLocalPort(error); if (port == -1) { ResetSocket(); m_pControlSocket->LogMessage(::Debug_Warning, _T("GetLocalPort failed: %s"), CSocket::GetErrorDescription(error).c_str()); return _T(""); } wxString portArguments; if (m_pSocketServer->GetAddressFamily() == CSocket::ipv6) { portArguments = wxString::Format(_T("|2|%s|%d|"), ip.c_str(), port); } else { portArguments = ip; portArguments += wxString::Format(_T(",%d,%d"), port / 256, port % 256); portArguments.Replace(_T("."), _T(",")); } return portArguments; }
CSocket* CTransferSocket::CreateSocketServer() { if (!m_pEngine->GetOptions()->GetOptionVal(OPTION_LIMITPORTS)) { // Ask the systen for a port CSocket* pServer = CreateSocketServer(0); return pServer; } // Try out all ports in the port range. // Upon first call, we try to use a random port fist, after that // increase the port step by step // Windows only: I think there's a bug in the socket implementation of // Windows: Even if using SO_REUSEADDR, using the same local address // twice will fail unless there are a couple of minutes between the // connection attempts. This may cause problems if transferring lots of // files with a narrow port range. static int start = 0; int low = m_pEngine->GetOptions()->GetOptionVal(OPTION_LIMITPORTS_LOW); int high = m_pEngine->GetOptions()->GetOptionVal(OPTION_LIMITPORTS_HIGH); if (low > high) low = high; if (start < low || start > high) { start = GetRandomNumber(low, high); wxASSERT(start >= low && start <= high); } CSocket* pServer = 0; int count = high - low + 1; while (count--) { pServer = CreateSocketServer(start++); if (pServer) break; if (start > high) start = low; } return pServer; }
BOOL CxServerSocketTCP::StartServer( int nPort, int nIOBufferSize /*=15*1024*1024*/ ) { m_nPort = nPort; m_nIOBufferSize = nIOBufferSize; InitializeSocket(); if ( !CreateSocketServer() ) return FALSE; unsigned int nThreadID = 0; m_ThreadContext.hThread = (HANDLE)::_beginthreadex( NULL, 0, WorkerThread, &m_ThreadContext, 0, &nThreadID ); if ( m_ThreadContext.hThread == NULL ) { return FALSE; } OnStartServer(); m_bStarted = TRUE; return TRUE; }
std::wstring CTransferSocket::SetupActiveTransfer(std::string const& ip) { ResetSocket(); m_pSocketServer = CreateSocketServer(); if (!m_pSocketServer) { controlSocket_.LogMessage(MessageType::Debug_Warning, _T("CreateSocketServer failed")); return std::wstring(); } int error; int port = m_pSocketServer->GetLocalPort(error); if (port == -1) { ResetSocket(); controlSocket_.LogMessage(MessageType::Debug_Warning, _T("GetLocalPort failed: %s"), CSocket::GetErrorDescription(error)); return std::wstring(); } if (engine_.GetOptions().GetOptionVal(OPTION_LIMITPORTS)) { port += static_cast<int>(engine_.GetOptions().GetOptionVal(OPTION_LIMITPORTS_OFFSET)); if (port <= 0 || port >= 65536) { controlSocket_.LogMessage(MessageType::Debug_Warning, _T("Port outside valid range")); return std::wstring(); } } std::wstring portArguments; if (m_pSocketServer->GetAddressFamily() == CSocket::ipv6) { portArguments = fz::sprintf(L"|2|%s|%d|", ip, port); } else { portArguments = fz::to_wstring(ip); fz::replace_substrings(portArguments, L".", L","); portArguments += fz::sprintf(L",%d,%d", port / 256, port % 256); } return portArguments; }