Download

Is it possible to create Tcp IP Connection using Headers from Engine\Source\ThirdParty Folder

Greetings everyone,

I try to build up a simple test program in which an Actor in UE lift up and down via data from a server. UE Program should be the client and my c++ ConsoleApp on the other PC should be the server. For the server code I used simply the basic example from Microsoft to test if I can get a connection between both PCs in the first step. For the UE part I used the tutorial from Rama.

Microsoft: https://msdn.microsoft.com/de-de/library/windows/desktop/ms737593(v=vs.85).aspx
Rama Link: https://wiki.unrealengine.com/TCP_Socket_Listener,Receive_Binary_Data_From_an_IP/Port_Into_UE4,(Full_Code_Sample)

I get both codes to work but they are unable to create a connection. Thats why I digged deeper into the engine source files and found some good looking header files in the ThirdParty folder of the engine which I want to try to use insteed of the Rama Tut code. I thought about trying to use tcp_client_socket.h or tcp_socket_win.h. So my question is first of all could that be a good way to get my program working. And second question is how can I use this classes? I couldn´t find a description in the documentation about how to use/include those classes from the ThirdParty folder.

Thanks to everyone who wants to help.

PS: I would also be very thanksful if anyone who already did something like that and get it to work in what way ever would like to share his code with me or let me know which classes he used. Thanks!

Hi!

We used the same solution as in Rama’s tutorial. Could your issue be related to firewall or ports closed?

I also used Rama tutorial on TCP sockets to communicate with a C# TCP server and finally a boost asio TCP server. I also created async sockets in UE4 based on the multichannel code in UE sockets library

I get a connection between 2 PCs via LAN with 2 console programms but wenn I try it with Rama´s code it doesn´t work. I debugged the code and find out that the FTcpSocketBuilder.Build() function, that runs when the constructor of FTcpSocketBuilder is activated, alwayse returns nullptr. Thats why the editor crashed violently at my PC cause Rama forget to check if ListenSocket is nullptr before ListenSocket->SetReceiveBufferSize(ReceiveBufferSize, NewSize);.
However, I could not find out why unreal is unable to create the Socket. Thats why I´m searching for alternatives and asked about how to use the classes from the Engine\Source\ThirdParty Folder.

PS: @ MPalacios and Fallonsnest:
Thanks a lot for your answer. Would it be possible that you send me your code or that you make screenshots from the server and client parts or send me a small working demo app if you dont want to share your project files? I would be very thanksful!

All the best
Epiphanie

Update:
I finally got something to work. However, I have tried two ways to get my data constantly updated on the screen. First of all I tried to implement a Timer with GetWorldTimerManager().SetTimer(Timerhandle, this, &ANetworkControlledActor::RecvMsgTimeCircle, 0.01, true); but this actually let the editor permanent crash. The second way I tried was to run the RecvMsgTimeCircle() function every Tick. This works but the performance is unbelievable bad. Can someone let me know what I do wrong and how to fix it? Thanks!



// Fill out your copyright notice in the Description page of Project Settings.

#include "NetworkCodeV3.h"
#include "NetworkControlledActor.h"


// Sets default values
ANetworkControlledActor::ANetworkControlledActor()
    : DataSize{ 22 }, Request{ "" }, sendSock{ nullptr }
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;
    Test();
}

// Called when the game starts or when spawned
void ANetworkControlledActor::BeginPlay()
{
    Super::BeginPlay();

}

// Called every frame
void ANetworkControlledActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    //// Methode 2 - very bad performance
    //RecvMsgTimeCircle();
    Debug(Request);
}

void ANetworkControlledActor::Test()
{
    // Stores the final server IP.
    FIPv4Address serverIP;
    // The ip address of the serverList Server.
    FString serverIpAddress = "192.168.1.10";
    // Port for connection to the serverList Server.
    int32 serverListPort = 4711;
    // Turn the string Ip into a usable ip and store it in serverIP.
    FIPv4Address::Parse(serverIpAddress, serverIP);

    // Create a network socket to connect to the serverList Server.
    sendSock = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("sendSock"), false);

    // Get a socketable internet address for use in the socket.
    TSharedRef < FInternetAddr > intAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();

    // Set the IP and PORT of the new socketable internet address.
    intAddr->SetIp(serverIP.GetValue());
    intAddr->SetPort(serverListPort);

    // Attempt a connection and store result in the connectionAttempt bool.
    bool connectionAttempt = sendSock->Connect(*intAddr);

    if (connectionAttempt) {
        Debug("Connect attempt SUCCESS!");

       

        /*
            // Methode 1 - Crashes the engine
            FTimerHandle Timerhandle;
            GetWorldTimerManager().SetTimer(Timerhandle, this,
            &ANetworkControlledActor::RecvMsgTimeCircle, 0.01, true);*/

    }
    else {
        Debug("Connect attempt failed.");
        return;
    }
}

void ANetworkControlledActor::RecvMsgTimeCircle()
{
    // check(sendSock);
    if (sendSock)
    {
        FArrayReaderPtr Datagram = MakeShareable(new FArrayReader(true));

        Datagram->Init(FMath::Min(DataSize, 65507u));

        int32 BytesRead = 0;
        if (sendSock->Recv(Datagram->GetData(), Datagram->Num(), BytesRead))
        {
            char* Data = (char*)Datagram->GetData();
            Data[BytesRead] = '\0';
            Request = UTF8_TO_TCHAR(Data);
        }
    }
}

void ANetworkControlledActor::Debug(FString Msg)
{
    if (GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 0.5f, FColor::Red, Msg);
    }
}