bool SocketImpl::Connect(const SocketAddress& address, const std::chrono::seconds& timeout /*= std::chrono::seconds(0)*/) { if (INVALID_SOCKET == m_sockfd) Init(AF_INET); if (timeout.count() > 0) SetBlocking(false); bool bResult = false; do { if (SOCKET_ERROR == connect(m_sockfd, address.GetAddress(), address.GetLength())) { if (timeout.count() == 0) break; int err = WSAGetLastError(); if (WSAEINPROGRESS != err && WSAEWOULDBLOCK != err && WSAEISCONN != err) break; if (!Poll(timeout, SELECT_READ | SELECT_WRITE | SELECT_ERROR)) break; if (GetSocketError() != 0) break; } bResult = true; } while (0); if (timeout.count() > 0) SetBlocking(true); return bResult; }
int TCPSocket::Connect( unsigned short timeout ) { fd_set rd, wr; long status; struct timeval tv; char err; socklen_t len = sizeof ( int ); tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO ( &rd ); FD_SET ( mSockFd, &rd ); FD_ZERO ( &wr ); FD_SET ( mSockFd, &wr ); SetBlocking ( false ); if ( ( status = connect ( mSockFd, reinterpret_cast<struct sockaddr*> ( &mCa ), sizeof ( mCa ) ) ) == -1 ) { if ( errno != EINPROGRESS ) { return static_cast<int> ( status ); } } status = select (mSockFd + 1, &rd, &wr, NULL, &tv); if ( !FD_ISSET ( mSockFd, &rd ) && !FD_ISSET ( mSockFd, &wr ) ) { return -2; } if ( getsockopt ( mSockFd, SOL_SOCKET, SO_ERROR, &err, &len ) < 0) { return -2; } if ( err == 0 ) { // TCP connection established. // Make the socket blocking again... SetBlocking ( true ); // And return from the function. return 0; } return -1; }
Int32 TcpSocketWin32::Receive( void * p_pData, const SizeType p_Size, const Time & p_Timeout ) { // Create a socket address storage sockaddr_in address; int addressSize = sizeof( address ); // Set blocking status Bool blocking = GetBlocking( ); if( blocking ) { SetBlocking( false ); } // Put the socket handle in a fdset fd_set fdset; FD_ZERO( &fdset ); FD_SET( m_Handle, &fdset ); // Set the time struct timeval tv; if( p_Timeout.AsMicroseconds( ) / 1000000ULL > g_MaxTimeout ) { tv.tv_sec = static_cast<long>( g_MaxTimeout ); tv.tv_usec = static_cast<long>( 0 ); } else { tv.tv_sec = static_cast<long>( p_Timeout.AsMicroseconds( ) / 1000000ULL ); tv.tv_usec = static_cast<long>( p_Timeout.AsMicroseconds( ) % 1000000ULL ); } // Select from the fdset int status = 0; if( ( status = select( static_cast<int>( m_Handle ) + 1, &fdset, NULL, NULL, &tv ) ) > 0 ) { // Receive the message int size = recv( m_Handle, reinterpret_cast<char*>( p_pData ), static_cast<int>( p_Size ), 0 ); // Restore the block status SetBlocking( blocking ); // return the received message's size return size; } // Reset the blocking status and return false SetBlocking( blocking ); return status; }
NetworkInterface::ServiceSocketInterface& WindowsNetwork::NewServiceSocket(aushort port, aushort numPending) { addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; addrinfo *result = nullptr; ScopedFuncCall blast([result]() { if(result) freeaddrinfo(result); }); char number[8]; // 64*1024+null if(port) _itoa_s(port, number, 10); if(getaddrinfo(NULL, port? number : NULL, &hints, &result)) throw std::exception("getaddrinfo failed."); SOCKET listener = INVALID_SOCKET; ScopedFuncCall clearSocket([&listener]() { if(listener != INVALID_SOCKET) closesocket(listener); }); listener = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if(listener == INVALID_SOCKET) throw std::exception("Error creating new Service Socket, creation failed."); SetBlocking(listener, false); if(bind(listener, result->ai_addr, static_cast<int>(result->ai_addrlen)) == SOCKET_ERROR) throw std::exception("Error creating new Service Socket, could not bind."); if(listen(listener, numPending? numPending : SOMAXCONN) == SOCKET_ERROR) throw std::exception("Error creating new Service Socket, could enter listen state."); std::unique_ptr<ServiceSocket> add(new ServiceSocket(listener, port)); clearSocket.Dont(); servers.insert(std::make_pair(static_cast<SocketInterface*>(add.get()), add.get())); return *add.release(); }
//////////////////////////////////////////////////////////// /// Construct the socket from a socket descriptor /// (for internal use only) //////////////////////////////////////////////////////////// SocketTCP::SocketTCP(SocketHelper::SocketType Descriptor) : mySocket (Descriptor), myPendingPacketSize(-1) { // Set blocking by default (should always be the case anyway) SetBlocking(true); }
//////////////////////////////////////////////////////////// /// Create the socket //////////////////////////////////////////////////////////// void SocketTCP::Create(SocketHelper::SocketType Descriptor) { // Use the given socket descriptor, or get a new one mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_STREAM, 0); myIsBlocking = true; // Reset the pending packet myPendingPacket.clear(); myPendingPacketSize = -1; // Setup default options if (IsValid()) { // To avoid the "Address already in use" error message when trying to bind to the same port int Yes = 1; if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to set socket option \"SO_REUSEADDR\" ; " << "binding to a same port may fail if too fast" << std::endl; } // Disable the Nagle algorithm (ie. removes buffering of TCP packets) if (setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to set socket option \"TCP_NODELAY\" ; " << "all your TCP packets will be buffered" << std::endl; } // Set blocking by default (should always be the case anyway) SetBlocking(true); } }
//////////////////////////////////////////////////////////// /// Create the socket //////////////////////////////////////////////////////////// void SocketUDP::Create(SocketHelper::SocketType Descriptor) { // Use the given socket descriptor, or get a new one mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_DGRAM, 0); myIsBlocking = true; // Clear the last port used myPort = 0; // Reset the pending packet myPendingHeaderSize = 0; myPendingPacket.clear(); myPendingPacketSize = -1; // Setup default options if (IsValid()) { // To avoid the "Address already in use" error message when trying to bind to the same port int Yes = 1; if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to set socket option \"reuse address\" ; " << "binding to a same port may fail if too fast" << std::endl; } // Enable broadcast by default if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to enable broadcast on UDP socket" << std::endl; } // Set blocking by default (should always be the case anyway) SetBlocking(true); } }
UDPConnectedSocket::UDPConnectedSocket(const std::string& server, const unsigned remoteport) : Socket(DATAGRAM) { sockaddr_in remoteAddr = ResolveHost(server, remoteport); if (connect(mySocket, (sockaddr*)&remoteAddr, sizeof(remoteAddr)) == SOCKET_ERROR) { throw network_error(std::string("Error while connecting: ") + GetErrorMsg()); } SetBlocking(false); }
bool plTcpSocket::ActiveOpenNonBlocking(plNetAddress & addr) { SetSocket(plNet::NewTCP()); if(fSocket == kBadSocket) return false; SetBlocking(false); if(plNet::Connect(fSocket, &addr.GetAddressInfo()) != 0) return ErrorClose(); return true; }
// // NetListenSocket::InitScan - Chapter X, page Y // Opens multiple ports to listen for connections. // void NetListenSocket::InitScan(int portnum_min, int portnum_max) { struct sockaddr_in sa; int portnum, x = 1; if ((m_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { EXIT_ASSERT exit(1); } if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&x, sizeof(x)) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; EXIT_ASSERT exit(1); } memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; for (portnum = portnum_min; portnum < portnum_max; portnum++) { sa.sin_port = htons(portnum); // bind to port if (bind(m_sock, (struct sockaddr *)&sa, sizeof(sa)) != SOCKET_ERROR) break; } if (portnum == portnum_max) { closesocket(m_sock); m_sock = INVALID_SOCKET; EXIT_ASSERT exit(1); } // set nonblocking - accept() blocks under some odd circumstances otherwise SetBlocking(false); // start listening if (listen(m_sock, 8) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; EXIT_ASSERT exit(1); } port = portnum; }
NetworkInterface::ConnectedSocketInterface& WindowsNetwork::BeginConnection(ServiceSocketInterface &listener) { auto real(servers.find(&listener)); if(real == servers.cend()) throw std::exception("Trying to create a connection from a socket not managed by this object."); SOCKET connSock = real->second->socket; SOCKET client = accept(connSock, NULL, NULL); if(client == INVALID_SOCKET) throw std::exception("Could not accept an incoming connection."); SetBlocking(client, false); ScopedFuncCall clearSocket([client]() { if(client) closesocket(client); }); std::unique_ptr<ConnectedSocket> add(new ConnectedSocket(nullptr, nullptr)); add->socket = client; clearSocket.Dont(); connections.insert(std::make_pair(static_cast<SocketInterface*>(add.get()), add.get())); return *add.release(); }
FDType GetSocket (bool is_v6) { // Make a socket for the appropriate // address family auto socket=::socket( is_v6 ? AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP ); // Make sure it's non-blocking SetBlocking(socket,false); return socket; }
// // NetListenSocket::Init - Chapter 19, page 674 // void NetListenSocket::Init(int portnum) { struct sockaddr_in sa; int value = 1; if ((m_sock = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { LOG_ASSERT("NetListenSocket Error: Init failed to create socket handle"); } if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value))== SOCKET_ERROR) { perror("NetListenSocket::Init: setsockopt"); closesocket(m_sock); m_sock = INVALID_SOCKET; LOG_ASSERT("NetListenSocket Error: Init failed to set socket options"); } memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = ADDR_ANY; sa.sin_port = htons(portnum); // bind to port if (bind(m_sock, (struct sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR) { perror("NetListenSocket::Init: bind"); closesocket(m_sock); m_sock = INVALID_SOCKET; LOG_ASSERT("NetListenSocket Error: Init failed to bind"); } // set nonblocking - accept() blocks under some odd circumstances otherwise SetBlocking(false); // start listening if (listen(m_sock, 256) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; LOG_ASSERT("NetListenSocket Error: Init failed to listen"); } port = portnum; }
//////////////////////////////////////////////////////////// /// Create the socket //////////////////////////////////////////////////////////// void SocketTCP::Create() { // Get a new socket descriptor mySocket = socket(PF_INET, SOCK_STREAM, 0); // To avoid the "Address already in use" error message when trying to bind to the same port char Yes = 1; if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, &Yes, sizeof(int)) == -1) { std::cerr << "Failed to set socket option \"reuse address\" ; " << "binding to a same port may fail if too fast" << std::endl; } // Set blocking by default (should always be the case anyway) SetBlocking(true); // Reset the pending packet myPendingPacket.Clear(); myPendingPacketSize = -1; }
//////////////////////////////////////////////////////////// /// Create the socket //////////////////////////////////////////////////////////// void SocketTCP::Create(SocketHelper::SocketType Descriptor) { // Use the given socket descriptor, or get a new one mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_STREAM, 0); myIsBlocking = true; // Reset the pending packet myPendingHeaderSize = 0; myPendingPacket.clear(); myPendingPacketSize = -1; // Setup default options if (IsValid()) { int Yes = 1; #ifndef SFML_SYSTEM_WINDOWS /* We must disable this in order to detect if ports are being used by other apps, or other instances of dolphin. This is also disabled in SFML 2.0, see http://www.sfml-dev.org/forum/viewtopic.php?t=3388 ...In fact, SO_REUSEADDR is only unsafe on Windows. See: http://stackoverflow.com/questions/14388706 */ // To avoid the "Address already in use" error message when trying to bind to the same port if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to set socket option \"SO_REUSEADDR\" ; " << "binding to a same port may fail if too fast" << std::endl; } #endif // Disable the Nagle algorithm (ie. removes buffering of TCP packets) if (setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) { std::cerr << "Failed to set socket option \"TCP_NODELAY\" ; " << "all your TCP packets will be buffered" << std::endl; } // Set blocking by default (should always be the case anyway) SetBlocking(true); } }
void NetListenSocket::Init(int portnum) { struct sockaddr_in sa; int value = 1; if ((m_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { GCC_ERROR("NetListenSocket Error: Init failed to created socket handle"); } if (setsockopt(m_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&value, sizeof(value)) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; GCC_ERROR("NetListenSocket Error: Init failed to set socket options"); } printf("Hey hey. Here is the INADDR_ANY = %d\n", INADDR_ANY); memset(&sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_addr.s_addr = INADDR_ANY; sa.sin_port = htons(portnum); if (bind(m_sock, (struct sockaddr*)&sa, sizeof(sa)) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; GCC_ERROR("NetListenSocket Error: Init failed to bind"); } SetBlocking(false); if (listen(m_sock, 256) == SOCKET_ERROR) { closesocket(m_sock); m_sock = INVALID_SOCKET; GCC_ERROR("NetListenSocket Error: Init failed to listen"); } port = portnum; }
//////////////////////////////////////////////////////////// /// Connect to another computer on a specified port //////////////////////////////////////////////////////////// Socket::Status SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout) { // Make sure our socket is valid if (!IsValid()) Create(); // Build the host address sockaddr_in SockAddr; memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero)); SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str()); SockAddr.sin_family = AF_INET; SockAddr.sin_port = htons(Port); if (Timeout <= 0) { // ----- We're not using a timeout : just try to connect ----- if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) { // Failed to connect return SocketHelper::GetErrorStatus(); } // Connection succeeded return Socket::Done; } else { // ----- We're using a timeout : we'll need a few tricks to make it work ----- // Save the previous blocking state bool IsBlocking = myIsBlocking; // Switch to non-blocking to enable our connection timeout if (IsBlocking) SetBlocking(false); // Try to connect to host if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0) { // We got instantly connected! (it may no happen a lot...) return Socket::Done; } // Get the error status Socket::Status Status = SocketHelper::GetErrorStatus(); // If we were in non-blocking mode, return immediatly if (!IsBlocking) return Status; // Otherwise, wait until something happens to our socket (success, timeout or error) if (Status == Socket::NotReady) { // Setup the selector fd_set Selector; FD_ZERO(&Selector); FD_SET(mySocket, &Selector); // Setup the timeout timeval Time; Time.tv_sec = static_cast<long>(Timeout); Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000; // Wait for something to write on our socket (would mean the connection has been accepted) if (select(static_cast<int>(mySocket + 1), NULL, &Selector, NULL, &Time) > 0) { // Connection succeeded Status = Socket::Done; } else { // Failed to connect before timeout is over Status = SocketHelper::GetErrorStatus(); } } // Switch back to blocking mode SetBlocking(true); return Status; } }
Socket::Status TcpSocket::Connect(const IpAddress& remoteAddress, unsigned short remotePort, Uint32 timeout) { // Create the internal socket if it doesn't exist Create(); // Create the remote address sockaddr_in address = priv::SocketImpl::CreateAddress(remoteAddress.ToInteger(), remotePort); if (timeout == 0) { // ----- We're not using a timeout: just try to connect ----- // Connect the socket if (connect(GetHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1) return priv::SocketImpl::GetErrorStatus(); // Connection succeeded return Done; } else { // ----- We're using a timeout: we'll need a few tricks to make it work ----- // Save the previous blocking state bool blocking = IsBlocking(); // Switch to non-blocking to enable our connection timeout if (blocking) SetBlocking(false); // Try to connect to the remote address if (connect(GetHandle(), reinterpret_cast<sockaddr*>(&address), sizeof(address)) >= 0) { // We got instantly connected! (it may no happen a lot...) return Done; } // Get the error status Status status = priv::SocketImpl::GetErrorStatus(); // If we were in non-blocking mode, return immediatly if (!blocking) return status; // Otherwise, wait until something happens to our socket (success, timeout or error) if (status == Socket::NotReady) { // Setup the selector fd_set selector; FD_ZERO(&selector); FD_SET(GetHandle(), &selector); // Setup the timeout timeval time; time.tv_sec = timeout / 1000; time.tv_usec = (timeout - time.tv_sec * 1000) * 1000; // Wait for something to write on our socket (which means that the connection request has returned) if (select(static_cast<int>(GetHandle() + 1), NULL, &selector, NULL, &time) > 0) { // At this point the connection may have been either accepted or refused. // To know whether it's a success or a failure, we must check the address of the connected peer if (GetRemoteAddress() != sf::IpAddress::None) { // Connection accepted status = Done; } else { // Connection refused status = priv::SocketImpl::GetErrorStatus(); } } else { // Failed to connect before timeout is over status = priv::SocketImpl::GetErrorStatus(); } } // Switch back to blocking mode SetBlocking(true); return status; } }
Bool TcpSocketWin32::Connect(const Address & p_Address, const Uint16 p_Port, const Time & p_Timeout, const Uint16 p_EndpointPort) { // Create the socket if ((m_Handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { bitLogNetErr( "Can not create the socket. Error: " << static_cast<Int32>(GetLastError()) ); return false; } // Bind the socket to a port sockaddr_in service; if (p_EndpointPort != 0) { service.sin_family = AF_INET; service.sin_addr.s_addr = htonl(INADDR_ANY); service.sin_port = htons(static_cast<u_short>(p_EndpointPort)); const int optVal = 1; const int optLen = sizeof(optVal); int rtn = setsockopt(m_Handle, SOL_SOCKET, SO_REUSEADDR, (const char*)&optVal, optLen); if( rtn != 0 ) { bitLogNetErr( "Can not set reusable socket. Error: " << static_cast<Int32>(GetLastError()) ); return false; } // Bind if (bind(m_Handle, reinterpret_cast<const sockaddr *>(&service), sizeof(service)) == SOCKET_ERROR) { bitLogNetErr( "Can not bind the socket. Error: " << static_cast<Int32>(GetLastError()) ); return false; } } // Create an object that's holding the host data service.sin_family = AF_INET; service.sin_addr.s_addr = htonl( static_cast<u_long>( p_Address.GetAddress( ) ) ); service.sin_port = htons( static_cast<u_short>( p_Port ) ); // We are using timeout // Get the blocking status and disable it. Bool blocking = GetBlocking( ); SetBlocking( false ); // Connect if( connect( m_Handle, ( const sockaddr * )&service, sizeof (sockaddr_in ) ) != 0 ) { // Ignore the WSAEWOULDBLOCK error DWORD lastError = GetLastError( ); if( lastError != WSAEWOULDBLOCK ) { Disconnect( ); return false; } } // We failed to connect, but we are waiting for the connection to establish struct timeval tv; if( p_Timeout.AsMicroseconds( ) / 1000000ULL > g_MaxTimeout ) { tv.tv_sec = static_cast<long>( g_MaxTimeout ); tv.tv_usec = static_cast<long>( 0 ); } else { tv.tv_sec = static_cast<long>( p_Timeout.AsMicroseconds( ) / 1000000ULL ); tv.tv_usec = static_cast<long>( p_Timeout.AsMicroseconds( ) % 1000000ULL ); } // Create a FD_SET, and add the m_Handle to the set fd_set fdset; FD_ZERO(&fdset); FD_SET(m_Handle, &fdset); // Select from the set if (select(static_cast<int>(m_Handle)+1, NULL, &fdset, NULL, &tv) > 0) { // Check if the address is valid. Address address = GetPeerAddress( ); if( address == p_Address ) { // The address is not 0, we successfully connected. SetBlocking( blocking ); return true; } } DWORD lastError = GetLastError(); // Failed to connect. Close the socket. Disconnect( ); // Failed. return false; }
void CProxySessionManager::ProcessNewConnection( SOCKET Server ) { CProxySession* pSession = NULL; SOCKET Client; // SOCKADDR_STORAGE from; // на Vista изменили размер SOCKADDR_STORAGE. теперь 128 байт. // на вс¤кий случай делаю 256 ( вдруг еще раз измен¤т !? ) // P.S. pigs !!! union _MY_SOCKADDR_STORAGE { SOCKADDR_STORAGE ss; char reserved[256]; } from; int fromlen = sizeof ( from ); char DrvBuffer[512]; int RetVal; Client = accept(Server, (struct sockaddr *)&from, &fromlen); if ( Client == INVALID_SOCKET ) { KLSTD_TRACE1( KLMC_TRACELEVEL, "ProcessNewConnection: accept error = %d", WSAGetLastError() ); return; } KLSTD_TRACE0( KLMC_TRACELEVEL, "ProcessNewConnection: connection accepted. create Session" ); SetBlocking( Client, true ); RetVal = recv ( Client, DrvBuffer, 500, 0 ); char Prefix[16]; memset( Prefix, '.', sizeof(Prefix) ); memcpy( Prefix, DrvBuffer, 10 ); Prefix[15] = 0; KLSTD_TRACE3 (KLMC_TRACELEVEL, "CProxySessionManager::Run => recv %d bytes from server [%s]. err = %d", RetVal, GetBinBufferTraceStringShort((const BYTE *)Prefix, sizeof(Prefix)).c_str(), WSAGetLastError() ); if (RetVal == 0 || RetVal == INVALID_SOCKET) { // CLOSESOCKET(Client); closesocket( Client ); return; } // обычный редирект через KAVSEND. ќставлено на вс¤ких случай, если не смогли переключитьс¤ на новую схему. if ( 0 == memcmp( DrvBuffer, KAVSEND_COMMAND, strlen( KAVSEND_COMMAND ) ) ) { KLSTD_TRACE0 (KLMC_TRACELEVEL, "CProxySessionManager::Run => KAVSEND" ); pSession = new CProxySession(m_hParent, this, m_hStopEvent ); if ( pSession ) { KLSTD_TRACE1 (KLMC_TRACELEVEL, "CProxySessionManager::Run => KAVSEND create session(%p)", pSession ); // тут клиентский сокет pSession->m_Flags |= FPS_GOT_KAVSEND; pSession->m_AcceptedSock = Client; pSession->ParseKavsendBuffer( DrvBuffer, RetVal ); pSession->StartProtocollers(); m_SessionList.push_back(pSession); //ƒобавим в список запущенную сессию if ( !pSession->StartClient() ) { KLSTD_TRACE0 (KLMC_TRACELEVEL, "CProxySessionManager::Run => Unable to start thread after KAVSEND"); AddClient( pSession ); } } return; } // редирект по новой схеме KAVSVC if ( 0 == memcmp( DrvBuffer, KAVSVC_COMMAND, strlen( KAVSVC_COMMAND ) )) { // сервисное соединение. “ут должны указыватьс¤ параметры сервера, // куда выполн¤ем соединение. ѕрокси должна соединитьс¤ туда и // создать ID сессии. pSession = new CProxySession(m_hParent, this, m_hStopEvent ); KLSTD_TRACE1 (KLMC_TRACELEVEL, "CProxySessionManager::Run => KAVSVC. session = %p", pSession ); if ( pSession ) { pSession->m_AcceptedSock = Client; pSession->m_Flags |= FPS_GOT_KAVSVC; pSession->ParseKavsvcBuffer( DrvBuffer, RetVal ); m_SessionList.push_back(pSession); //ƒобавим в список запущенную сессию if ( !pSession->StartClient() ) { KLSTD_TRACE0 (KLMC_TRACELEVEL, "CProxySessionManager::Run => Unable to start thread after KAVSVC"); AddClient( pSession ); } } return; } // продолжение редиректа по новой схеме. ћы законнектились на сервер. // “еперь нужно найти сессию с установленным серверным соединением по указанному ID // !! TODO : можно избежать лишнего запуска потока. дл¤ этого нужно засинхронизировать // уже работающий поток с серверным соединением с текущим потоком. if ( 0 == memcmp( DrvBuffer, KAVCONN_ID, strlen( KAVCONN_ID ) ) ) { __int64 ID = *(__int64*) ( (PCHAR)DrvBuffer + 10 ); KLSTD_TRACE1 (KLMC_TRACELEVEL, "CProxySessionManager::Run => KAVCONN_ID 0x%I64x", ID ); if ( pSession = FindSessionByID( ID ) ) { KLSTD_TRACE1 (KLMC_TRACELEVEL, "CProxySessionManager::Run => Session %p found by KAVCONN_ID", pSession ); // тут клиентский сокет pSession->m_client.AssignSocket( Client ); pSession->m_client.PrepareSocket(); GetLocalName( pSession->m_client.Socket(), pSession->m_Localhost, sizeof ( pSession->m_Localhost ) ); pSession->m_Flags |= FPS_GOT_KAVCONN_ID | FPS_ESTABLISHED | FPS_CLIENT_CONNECTED; pSession->StartProtocollers(); // запускаем поток сессии if ( !pSession->StartClient() ) { KLSTD_TRACE0 (KLMC_TRACELEVEL, "CProxySessionManager::Run => Unable to start thread after KAVCONN_ID"); AddClient( pSession ); } } else { KLSTD_TRACE0 (KLMC_TRACELEVEL, "CProxySessionManager::Run => Session NOT found by KAVCONN_ID" ); } return; } }
void sfTcpSocket_SetBlocking(sfTcpSocket* socket, sfBool blocking) { CSFML_CALL(socket, SetBlocking(blocking == sfTrue)); }
ProtoChannel::ProtoChannel() : listener(NULL), notifier(NULL), notify_flags(0), blocking_status(true), #ifdef WIN32 input_handle(INVALID_HANDLE), input_ready(false), output_handle(INVALID_HANDLE), output_ready(false) #else descriptor(INVALID_HANDLE) #endif // if/else WIN32/UNIX { } ProtoChannel::~ProtoChannel() { if (notifier) SetNotifier(NULL); if (listener) { delete listener; listener = NULL; } } bool ProtoChannel::SetNotifier(ProtoChannel::Notifier* theNotifier) { if (notifier != theNotifier) { if (IsOpen()) { // 1) Detach old notifier, if any if (notifier) { notifier->UpdateChannelNotification(*this, 0); if (!theNotifier) { // Reset channel to "blocking" if(!SetBlocking(true)) PLOG(PL_ERROR, "ProtoChannel::SetNotifier() SetBlocking(true) error\n", GetErrorString()); } } else { // Set channel to "non-blocking" if(!SetBlocking(false)) { PLOG(PL_ERROR, "ProtoChannel::SetNotifier() SetBlocking(false) error\n", GetErrorString()); return false; } } // 2) Set and update new notifier (if applicable) notifier = theNotifier; if (!UpdateNotification()) { notifier = NULL; return false; } } else { notifier = theNotifier; } } return true; } // end ProtoChannel::SetNotifier() bool ProtoChannel::UpdateNotification() { if (notifier) { if (IsOpen() && !SetBlocking(false)) { PLOG(PL_ERROR, "ProtoChannel::UpdateNotification() SetBlocking() error\n"); return false; } return notifier->UpdateChannelNotification(*this, notify_flags); } return true; } // end ProtoChannel::UpdateNotification() bool ProtoChannel::SetBlocking(bool blocking) { #ifdef UNIX if (IsOpen() && (blocking_status != blocking)) { if (blocking) { if(-1 == fcntl(descriptor, F_SETFL, fcntl(descriptor, F_GETFL, 0) & ~O_NONBLOCK)) { PLOG(PL_ERROR, "ProtoChannel::SetBlocking() fcntl(F_SETFL(~O_NONBLOCK)) error: %s\n", GetErrorString()); return false; } } else { if(-1 == fcntl(descriptor, F_SETFL, fcntl(descriptor, F_GETFL, 0) | O_NONBLOCK)) { PLOG(PL_ERROR, "ProtoChannel::SetBlocking() fcntl(F_SETFL(O_NONBLOCK)) error: %s\n", GetErrorString()); return false; } } blocking_status = blocking; } #endif // UNIX return true; //Note: taken care automatically under Win32 by WSAAsyncSelect(), etc } // end ProtoChannel::SetBlocking(bool blocking)