Files
UnrealEngineUWP/Engine/Source/Runtime/NetworkFileSystem/Private/NetworkFileServer.cpp
Max Preussner 3aece47882 Docs: Removed file comments and added missing code documentation
Please note that file comments had no purpose in nearly all cases and just added visual clutter. The two files that had meaningful file comments had their comments moved into the corresponding classes. There are still hundreds of file comments left in other files that will be removed over time.

Also cleaned up some random stuff along the way:
- relative paths to public headers within the same module are no longer necessary (automatically discovered by UBT now)
- header guards are deprecated, use #pragma once instead (all compilers support it now)
- space between multiple template brackets is no longer required (all compilers support >> now)
- NULL to nullptr, OVERRIDE to override
- spelling errors, whitespace, line breaks

[CL 2104067 by Max Preussner in Main branch]
2014-06-12 23:22:18 -04:00

274 lines
7.0 KiB
C++

// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#include "NetworkFileSystemPrivatePCH.h"
#include "TargetPlatform.h"
#include "NetworkFileServerConnection.h"
class FNetworkFileServerClientConnectionThreaded
: public FNetworkFileServerClientConnection
,protected FRunnable
{
public:
FNetworkFileServerClientConnectionThreaded(FSocket* InSocket, const FFileRequestDelegate& InFileRequestDelegate,
const FRecompileShadersDelegate& InRecompileShadersDelegate, const TArray<ITargetPlatform*>& InActiveTargetPlatforms )
: FNetworkFileServerClientConnection( InFileRequestDelegate,InRecompileShadersDelegate,InActiveTargetPlatforms)
,Socket(InSocket)
{
Running.Set(true);
StopRequested.Reset();
#if UE_BUILD_DEBUG
// this thread needs more space in debug builds as it tries to log messages and such
const static uint32 NetworkFileServerThreadSize = 2 * 1024 * 1024;
#else
const static uint32 NetworkFileServerThreadSize = 8 * 1024;
#endif
WorkerThread = FRunnableThread::Create(this, TEXT("FNetworkFileServerClientConnection"), NetworkFileServerThreadSize, TPri_AboveNormal);
}
virtual bool Init()
{
return true;
}
virtual uint32 Run()
{
while (!StopRequested.GetValue())
{
// read a header and payload pair
FArrayReader Payload;
if (!FNFSMessageHeader::ReceivePayload(Payload, FSimpleAbstractSocket_FSocket(Socket)))
break;
// now process the contents of the payload
FBufferArchive Out;
FNetworkFileServerClientConnection::ProcessPayload(Payload,Out);
if ( !FNFSMessageHeader::WrapAndSendPayload(Out, FSimpleAbstractSocket_FSocket(Socket)))
break;
}
return true;
}
virtual void Stop()
{
StopRequested.Set(true);
}
virtual void Exit()
{
Socket->Close();
ISocketSubsystem::Get()->DestroySocket(Socket);
Running.Set(false);
}
bool IsRunning()
{
return (Running.GetValue() != 0);
}
~FNetworkFileServerClientConnectionThreaded()
{
WorkerThread->Kill(true);
}
private:
FSocket* Socket;
FThreadSafeCounter StopRequested;
FThreadSafeCounter Running;
FRunnableThread* WorkerThread;
};
/* FNetworkFileServer constructors
*****************************************************************************/
FNetworkFileServer::FNetworkFileServer( int32 InPort, const FFileRequestDelegate* InFileRequestDelegate,const FRecompileShadersDelegate* InRecompileShadersDelegate, const TArray<ITargetPlatform*>& InActiveTargetPlatforms )
:ActiveTargetPlatforms(InActiveTargetPlatforms)
{
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));
}
}
}
}
FNetworkFileServer::~FNetworkFileServer()
{
// Kill the running thread.
if( Thread != NULL )
{
Thread->Kill(true);
delete Thread;
Thread = NULL;
}
// We are done with the socket.
Socket->Close();
ISocketSubsystem::Get()->DestroySocket(Socket);
Socket = NULL;
}
/* FRunnable overrides
*****************************************************************************/
uint32 FNetworkFileServer::Run( )
{
Running.Set(true);
// go until requested to be done
while (!StopRequested.GetValue())
{
bool bReadReady = false;
// clean up closed connections
for (int32 ConnectionIndex = 0; ConnectionIndex < Connections.Num(); ++ConnectionIndex)
{
FNetworkFileServerClientConnectionThreaded* Connection = Connections[ConnectionIndex];
if (!Connection->IsRunning())
{
UE_LOG(LogFileServer, Display, TEXT( "Client %s disconnected." ), *Connection->GetDescription() );
Connections.RemoveAtSwap(ConnectionIndex);
delete Connection;
}
}
// check for incoming connections
if (Socket->HasPendingConnection(bReadReady) && bReadReady)
{
FSocket* ClientSocket = Socket->Accept(TEXT("Remote Console Connection"));
if (ClientSocket != NULL)
{
FNetworkFileServerClientConnectionThreaded* Connection = new FNetworkFileServerClientConnectionThreaded(ClientSocket, FileRequestDelegate, RecompileShadersDelegate, ActiveTargetPlatforms);
Connections.Add(Connection);
UE_LOG(LogFileServer, Display, TEXT( "Client %s connected." ), *Connection->GetDescription() );
}
}
FPlatformProcess::Sleep(0.25f);
}
return 0;
}
void FNetworkFileServer::Exit( )
{
// close all connections
for (int32 ConnectionIndex = 0; ConnectionIndex < Connections.Num(); ConnectionIndex++)
{
delete Connections[ConnectionIndex];
}
Connections.Empty();
}
/* INetworkFileServer overrides
*****************************************************************************/
bool FNetworkFileServer::GetAddressList( TArray<TSharedPtr<FInternetAddr> >& OutAddresses ) const
{
if (ListenAddr.IsValid())
{
FString ListenAddressString = ListenAddr->ToString(true);
if (ListenAddressString.StartsWith(TEXT("0.0.0.0")))
{
if (ISocketSubsystem::Get()->GetLocalAdapterAddresses(OutAddresses))
{
for (int32 AddressIndex = 0; AddressIndex < OutAddresses.Num(); ++AddressIndex)
{
OutAddresses[AddressIndex]->SetPort(ListenAddr->GetPort());
}
}
}
else
{
OutAddresses.Add(ListenAddr);
}
}
return (OutAddresses.Num() > 0);
}
bool FNetworkFileServer::IsItReadyToAcceptConnections(void) const
{
return (Running.GetValue() != 0);
}
int32 FNetworkFileServer::NumConnections(void) const
{
return Connections.Num();
}
void FNetworkFileServer::Shutdown(void)
{
Stop();
}