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));
			}
		}
	}

 }