Networking TCP receive is not working

Well well well guys…

I am playing around with some TCP code these days and searched the whole forums and stopped especially for Rama’s tutorials and scripts. Now there came up a question which I cannot find a solution for. Maybe I its just a error in reasoning.

Well, I am using this code, for example to send a string to my server what is working fine:


void UTCPConnection::sendPacket(){



	FSocket* Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);
	FString address = TEXT("127.0.0.1");
	int32 port = 8000;
	FIPv4Address ip;
	FIPv4Address::Parse(address, ip);

	TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	addr->SetIp(ip.GetValue());
	addr->SetPort(port);

	bool connected = Socket->Connect(*addr);

	FString serialized = TEXT("teststring|56");
	TCHAR *serializedChar = serialized.GetCharArray().GetData();
	int32 size = FCString::Strlen(serializedChar);
	int32 sent = 0;

	bool successful = Socket->Send((uint8*)TCHAR_TO_UTF8(serializedChar), size, sent);
	
	
	}

But what if I want to receive a string back from my server ? I addad this on the bottom of my code, but its not working at all :



TArray<uint8> ReceivedData;

	uint32 Size;
	while (Socket->HasPendingData(Size))
	{
		ReceivedData.Init(FMath::Min(Size, 65507u));

		int32 Read = 0;
		Socket->Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);

		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Data Read! %d"), ReceivedData.Num()));
	}


Same problem here without sending data:



bool UTCPConnection::Connect(){
	
	Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);
	FString address = TEXT("127.0.0.1");
	int32 port = 8000;
	FIPv4Address::Parse(address, ip);
	TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	addr->SetIp(ip.GetValue());
	addr->SetPort(port);

	

	bool connected = Socket->Connect(*addr);

	if (connected){
		
			UE_LOG(LogTemp, Warning, TEXT("Socket connection successful"));
			TArray<uint8> ReceivedData;

			uint32 Size;
			while (Socket->HasPendingData(Size))
			{
				ReceivedData.Init(FMath::Min(Size, 65507u));

				int32 Read = 0;
				Socket->Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);

				GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Data Read! %d"), ReceivedData.Num()));
			}
			return true;
				
	}
	else{
		UE_LOG(LogTemp, Warning, TEXT("Cannot create socket connection"));
		return false;
	}
	Socket->Close();
}


I can’t help myself…

Hi there!

My code sample is complete in the wiki, specifically for receiving TCP data,

A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums,Receive_Binary_Data_From_an_IP/Port_Into_UE4,(Full_Code_Sample)

Are you setting up the timer to constantly check for received data, and then running that while loop you posted above?

You have to set the timer and constantly check, or use delegates.

Basically I am asking, is your code constantly checking for incoming data?

If you follow my wiki code and/or Alfalfaprossen’s code exactly, you should be able to get it working!

Congrats on getting sending TCP data working!

Rama

Hello Rama and thank you for answering. I am coming from Java/C# and C++ is very hard for me at the moment but it is getting better more and more.
Also I have some problems understand the mechanism behind the TCP sockets etc.

No, I dont. So that means I cannot receive a packet after connecting to the server without a loop and/or timers ?
Well ok, so I have the following plan now.

First I gonna connect to the server with something like this:


bool UTCPConnection::Connect(){
	
	Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);
	FString address = TEXT("127.0.0.1");
	int32 port = 8000;
	FIPv4Address::Parse(address, ip);
	TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	addr->SetIp(ip.GetValue());
	addr->SetPort(port);

	

	bool connected = Socket->Connect(*addr);

	if (connected){
		
			UE_LOG(LogTemp, Warning, TEXT("Socket connection successful"));
			return true;
				
	}
	else{
		UE_LOG(LogTemp, Warning, TEXT("Cannot create socket connection"));
		return false;
	}
	
}

Then inside this “connect” which is returning true or false I shall start another function with this code inside :


TArray<uint8> ReceivedData;

	uint32 Size;
	while (Socket->HasPendingData(Size))
	{
		ReceivedData.Init(FMath::Min(Size, 65507u));

		int32 Read = 0;
		Socket->Recv(ReceivedData.GetData(), ReceivedData.Num(), Read);

		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("Data Read! %d"), ReceivedData.Num()));
	}

But how to add a timer to this which is repeating this ? Just in BP with an event tick ? And do I need to create this socket again after the connection,
because I don’t know how to access the socket inside another function without using this again:


Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);
	FString address = TEXT("127.0.0.1");
	int32 port = 8000;
	FIPv4Address::Parse(address, ip);
	TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
	addr->SetIp(ip.GetValue());
	addr->SetPort(port);