void FMakeshiftServer::Init() { ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); if (SocketSubsystem != nullptr) { FString SocketDescription("MakeshiftServerSocket"); FIPv4Endpoint Endpoint(FIPv4Address(192, 168, 1, 205), 9915); UE_LOG_ONLINE(Warning, TEXT("Connecting to %s"), *Endpoint.ToString()); //Socket = FTcpSocketBuilder(*SocketName).BoundToEndpoint(Endpoint).Build(); bool Error = true; Socket = SocketSubsystem->CreateSocket(NAME_Stream, *SocketDescription, true); if (Socket != nullptr) { Error = !Socket->Connect(*SocketSubsystem->CreateInternetAddr(Endpoint.GetAddress().GetValue(), Endpoint.GetPort())); } if (Error) { UE_LOG_ONLINE(Warning, TEXT("Failed to connect to %s"), *Endpoint.ToString()); } else { int32 sent; char data[] = "hello there"; Socket->Send(reinterpret_cast<const uint8 *>(data), 5, sent); UE_LOG_ONLINE(Warning, TEXT("Sent %d bytes"), sent); } } }
/** * Resolves the specified host name */ void FResolveInfoAsync::DoWork() { int32 AttemptCount = 0; ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(); Addr = SocketSubsystem->CreateInternetAddr(0,0); // Make up to 3 attempts to resolve it do { ErrorCode = SocketSubsystem->GetHostByName(HostName, *Addr); if (ErrorCode != SE_NO_ERROR) { if (ErrorCode == SE_HOST_NOT_FOUND || ErrorCode == SE_NO_DATA || ErrorCode == SE_ETIMEDOUT) { // Force a failure AttemptCount = 3; } } AttemptCount++; } while (ErrorCode != SE_NO_ERROR && AttemptCount < 3 && bShouldAbandon == false); if (ErrorCode == SE_NO_ERROR) { // Cache for reuse SocketSubsystem->AddHostNameToCache(HostName, Addr); } }
void FMakeshiftServer::Shutdown() { ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); if (SocketSubsystem != nullptr && Socket != nullptr) { SocketSubsystem->DestroySocket(Socket); } }
bool FPerfCounters::Initialize() { // get the requested port from the command line (if specified) int32 StatsPort = -1; FParse::Value(FCommandLine::Get(), TEXT("statsPort="), StatsPort); if (StatsPort < 0) { UE_LOG(LogPerfCounters, Log, TEXT("FPerfCounters JSON socket disabled.")); return true; } // get the socket subsystem ISocketSubsystem* SocketSystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); if (SocketSystem == nullptr) { UE_LOG(LogPerfCounters, Error, TEXT("FPerfCounters unable to get socket subsystem")); return false; } // make our listen socket Socket = SocketSystem->CreateSocket(NAME_Stream, TEXT("FPerfCounters")); if (Socket == nullptr) { UE_LOG(LogPerfCounters, Error, TEXT("FPerfCounters unable to allocate stream socket")); return false; } // make us non blocking Socket->SetNonBlocking(true); // create a localhost binding for the requested port TSharedRef<FInternetAddr> LocalhostAddr = SocketSystem->CreateInternetAddr(0x7f000001 /* 127.0.0.1 */, StatsPort); if (!Socket->Bind(*LocalhostAddr)) { UE_LOG(LogPerfCounters, Error, TEXT("FPerfCounters unable to bind to %s"), *LocalhostAddr->ToString(true)); return false; } StatsPort = Socket->GetPortNo(); // log the port UE_LOG(LogPerfCounters, Display, TEXT("FPerfCounters listening on port %d"), StatsPort); // for now, jack this up so we can send in one go int32 NewSize; Socket->SetSendBufferSize(512 * 1024, NewSize); // best effort 512k buffer to avoid not being able to send in one go // listen on the port if (!Socket->Listen(16)) { UE_LOG(LogPerfCounters, Error, TEXT("FPerfCounters unable to listen on socket")); return false; } return true; }
FPerfCounters::~FPerfCounters() { if (Socket) { ISocketSubsystem* SocketSystem = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM); if (SocketSystem) { SocketSystem->DestroySocket(Socket); } Socket = nullptr; } }
void UIpNetDriver::LowLevelDestroy() { Super::LowLevelDestroy(); // Close the socket. if( Socket && !HasAnyFlags(RF_ClassDefaultObject) ) { ISocketSubsystem* SocketSubsystem = GetSocketSubsystem(); if( !Socket->Close() ) { UE_LOG(LogExit, Log, TEXT("closesocket error (%i)"), (int32)SocketSubsystem->GetLastErrorCode() ); } // Free the memory the OS allocated for this socket SocketSubsystem->DestroySocket(Socket); Socket = NULL; UE_LOG(LogExit, Log, TEXT("%s shut down"),*GetDescription() ); } }
FSlateRemoteServer::FSlateRemoteServer( ISocketSubsystem& InSocketSubsystem, const FIPv4Endpoint& InServerEndpoint ) : HighestMessageReceived(0xFFFF) , ReplyAddr(InSocketSubsystem.CreateInternetAddr()) , ServerSocket(nullptr) , SocketSubsystem(InSocketSubsystem) , TimeSinceLastPing(200.0f) , Timestamp(0.0) { StartServer(InServerEndpoint); }
bool FTCPTransport::Initialize(const TCHAR* InHostIp) { ISocketSubsystem* SSS = ISocketSubsystem::Get(); FString HostIp = InHostIp; // the protocol isn't required for tcp it's assumed by default HostIp.RemoveFromStart(TEXT("tcp://")); // convert the string to a ip addr structure // DEFAULT_TCP_FILE_SERVING_PORT is overridden TSharedRef<FInternetAddr> Addr = SSS->CreateInternetAddr(0, DEFAULT_TCP_FILE_SERVING_PORT); bool bIsValid; Addr->SetIp(*HostIp, bIsValid); if (bIsValid) { // create the socket FileSocket = SSS->CreateSocket(NAME_Stream, TEXT("FNetworkPlatformFile tcp")); // try to connect to the server if (FileSocket->Connect(*Addr) == false) { // on failure, shut it all down SSS->DestroySocket(FileSocket); FileSocket = NULL; UE_LOG(LogNetworkPlatformFile, Error, TEXT("Failed to connect to file server at %s."), *Addr->ToString(true)); } } #if USE_MCSOCKET_FOR_NFS MCSocket = new FMultichannelTcpSocket(FileSocket, 64 * 1024 * 1024); #endif return ( FileSocket || MCSocket ); }
bool UIpNetDriver::InitBase( bool bInitAsClient, FNetworkNotify* InNotify, const FURL& URL, bool bReuseAddressAndPort, FString& Error ) { if (!Super::InitBase(bInitAsClient, InNotify, URL, bReuseAddressAndPort, Error)) { return false; } ISocketSubsystem* SocketSubsystem = GetSocketSubsystem(); if (SocketSubsystem == NULL) { UE_LOG(LogNet, Warning, TEXT("Unable to find socket subsystem")); return false; } // Derived types may have already allocated a socket if (Socket == NULL) { // Create UDP socket and enable broadcasting. Socket = SocketSubsystem->CreateSocket(NAME_DGram, TEXT("Unreal")); } if( Socket == NULL ) { Socket = 0; Error = FString::Printf( TEXT("WinSock: socket failed (%i)"), (int32)SocketSubsystem->GetLastErrorCode() ); return false; } if (SocketSubsystem->RequiresChatDataBeSeparate() == false && Socket->SetBroadcast() == false) { Error = FString::Printf( TEXT("%s: setsockopt SO_BROADCAST failed (%i)"), SocketSubsystem->GetSocketAPIName(), (int32)SocketSubsystem->GetLastErrorCode() ); return false; } if (Socket->SetReuseAddr(bReuseAddressAndPort) == false) { UE_LOG(LogNet, Log, TEXT("setsockopt with SO_REUSEADDR failed")); } if (Socket->SetRecvErr() == false) { UE_LOG(LogNet, Log, TEXT("setsockopt with IP_RECVERR failed")); } // Increase socket queue size, because we are polling rather than threading // and thus we rely on Windows Sockets to buffer a lot of data on the server. int32 RecvSize = bInitAsClient ? 0x8000 : 0x20000; int32 SendSize = bInitAsClient ? 0x8000 : 0x20000; Socket->SetReceiveBufferSize(RecvSize,RecvSize); Socket->SetSendBufferSize(SendSize,SendSize); UE_LOG(LogInit, Log, TEXT("%s: Socket queue %i / %i"), SocketSubsystem->GetSocketAPIName(), RecvSize, SendSize ); // Bind socket to our port. LocalAddr = SocketSubsystem->GetLocalBindAddr(*GLog); LocalAddr->SetPort(0); if(!bInitAsClient) { // Init as a server. LocalAddr->SetPort(URL.Port); } int32 AttemptPort = LocalAddr->GetPort(); int32 BoundPort = SocketSubsystem->BindNextPort( Socket, *LocalAddr, MaxPortCountToTry + 1, 1 ); if (BoundPort == 0) { Error = FString::Printf( TEXT("%s: binding to port %i failed (%i)"), SocketSubsystem->GetSocketAPIName(), AttemptPort, (int32)SocketSubsystem->GetLastErrorCode() ); return false; } if( Socket->SetNonBlocking() == false ) { Error = FString::Printf( TEXT("%s: SetNonBlocking failed (%i)"), SocketSubsystem->GetSocketAPIName(), (int32)SocketSubsystem->GetLastErrorCode()); return false; } // Success. return true; }
void UIpNetDriver::TickDispatch( float DeltaTime ) { Super::TickDispatch( DeltaTime ); ISocketSubsystem* SocketSubsystem = GetSocketSubsystem(); // Process all incoming packets. uint8 Data[NETWORK_MAX_PACKET]; TSharedRef<FInternetAddr> FromAddr = SocketSubsystem->CreateInternetAddr(); for( ; Socket != NULL; ) { int32 BytesRead = 0; // Get data, if any. CLOCK_CYCLES(RecvCycles); bool bOk = Socket->RecvFrom(Data, sizeof(Data), BytesRead, *FromAddr); UNCLOCK_CYCLES(RecvCycles); // Handle result. if( bOk == false ) { ESocketErrors Error = SocketSubsystem->GetLastErrorCode(); if(Error == SE_EWOULDBLOCK || Error == SE_NO_ERROR) { // No data or no error? break; } else { if( Error != SE_ECONNRESET && Error != SE_UDP_ERR_PORT_UNREACH ) { UE_LOG(LogNet, Warning, TEXT("UDP recvfrom error: %i (%s) from %s"), (int32)Error, SocketSubsystem->GetSocketError(Error), *FromAddr->ToString(true)); break; } } } // Figure out which socket the received data came from. UIpConnection* Connection = NULL; if (GetServerConnection() && (*GetServerConnection()->RemoteAddr == *FromAddr)) { Connection = GetServerConnection(); } for( int32 i=0; i<ClientConnections.Num() && !Connection; i++ ) { UIpConnection* TestConnection = (UIpConnection*)ClientConnections[i]; check(TestConnection); if(*TestConnection->RemoteAddr == *FromAddr) { Connection = TestConnection; } } if( bOk == false ) { if( Connection ) { if( Connection != GetServerConnection() ) { // We received an ICMP port unreachable from the client, meaning the client is no longer running the game // (or someone is trying to perform a DoS attack on the client) // rcg08182002 Some buggy firewalls get occasional ICMP port // unreachable messages from legitimate players. Still, this code // will drop them unceremoniously, so there's an option in the .INI // file for servers with such flakey connections to let these // players slide...which means if the client's game crashes, they // might get flooded to some degree with packets until they timeout. // Either way, this should close up the usual DoS attacks. if ((Connection->State != USOCK_Open) || (!AllowPlayerPortUnreach)) { if (LogPortUnreach) { UE_LOG(LogNet, Log, TEXT("Received ICMP port unreachable from client %s. Disconnecting."), *FromAddr->ToString(true)); } Connection->CleanUp(); } } } else { if (LogPortUnreach) { UE_LOG(LogNet, Log, TEXT("Received ICMP port unreachable from %s. No matching connection found."), *FromAddr->ToString(true)); } } } else { // If we didn't find a client connection, maybe create a new one. if( !Connection ) { // Determine if allowing for client/server connections const bool bAcceptingConnection = Notify->NotifyAcceptingConnection() == EAcceptConnection::Accept; if (bAcceptingConnection) { Connection = ConstructObject<UIpConnection>(NetConnectionClass); check(Connection); Connection->InitRemoteConnection( this, Socket, FURL(), *FromAddr, USOCK_Open); Notify->NotifyAcceptedConnection( Connection ); AddClientConnection(Connection); } } // Send the packet to the connection for processing. if( Connection ) { Connection->ReceivedRawPacket( Data, BytesRead ); } } } }
FNetworkFileServer::FNetworkFileServer( int32 InPort, const FFileRequestDelegate* InFileRequestDelegate,const FRecompileShadersDelegate* InRecompileShadersDelegate, const TArray<ITargetPlatform*>& InActiveTargetPlatforms ) :ActiveTargetPlatforms(InActiveTargetPlatforms) { if(InPort <0) { InPort = DEFAULT_TCP_FILE_SERVING_PORT; } Running.Set(false); StopRequested.Set(false); UE_LOG(LogFileServer, Warning, TEXT("Unreal Network File Server starting up...")); if (InFileRequestDelegate && InFileRequestDelegate->IsBound()) { FileRequestDelegate = *InFileRequestDelegate; } if (InRecompileShadersDelegate && InRecompileShadersDelegate->IsBound()) { RecompileShadersDelegate = *InRecompileShadersDelegate; } // make sure sockets are going ISocketSubsystem* SocketSubsystem = ISocketSubsystem::Get(); if(!SocketSubsystem) { UE_LOG(LogFileServer, Error, TEXT("Could not get socket subsystem.")); } else { // create a server TCP socket Socket = SocketSubsystem->CreateSocket(NAME_Stream, TEXT("FNetworkFileServer tcp-listen")); if(!Socket) { UE_LOG(LogFileServer, Error, TEXT("Could not create listen socket.")); } else { // listen on any IP address ListenAddr = SocketSubsystem->GetLocalBindAddr(*GLog); ListenAddr->SetPort(InPort); Socket->SetReuseAddr(); // bind to the address if (!Socket->Bind(*ListenAddr)) { UE_LOG(LogFileServer, Warning, TEXT("Failed to bind listen socket %s in FNetworkFileServer"), *ListenAddr->ToString(true)); } // listen for connections else if (!Socket->Listen(16)) { UE_LOG(LogFileServer, Warning, TEXT("Failed to listen on socket %s in FNetworkFileServer"), *ListenAddr->ToString(true)); } else { // set the port on the listen address to be the same as the port on the socket int32 port = Socket->GetPortNo(); check((InPort == 0 && port != 0) || port == InPort); ListenAddr->SetPort(port); // now create a thread to accept connections Thread = FRunnableThread::Create(this, TEXT("FNetworkFileServer"), 8 * 1024, TPri_AboveNormal); UE_LOG(LogFileServer, Display, TEXT("Unreal Network File Server is ready for client connections on %s!"), *ListenAddr->ToString(true)); } } } }