FSocket->Recv no data response

I have gathered as much data as I could find in the documentation as well as around the web on UE4’s socket networking ability. I have successfully connected to a server and sent data. The server echos the sent data back to the client. However, FSocket->Recv(blah, blah, blah) isn’t reading any data back from the server. I have another client written in C# that does receive the data echo.


void ANetwork_Test::TestTransmit(FString outData){
     
     // Stores the final server IP.
     FIPv4Address serverIP;
     // The ip address of the serverList Server.
     FString serverIpAddress = "192.168.1.11"; 
     // Port for connection to the serverList Server.
     int32 serverListPort = 24575;
     // 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){
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Connect attempt SUCCESS!"));
         SendData(sendSock,outData);
     }
     else{
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Connect attempt failed."));
         return;
     }
 }

This is the SendData code:


void ANetwork_Test::SendData(FSocket* client, FString data){
     TCHAR *sendData = data.GetCharArray().GetData();
     int32 size = FCString::Strlen(sendData);
     int32 sent = 0;
     uint8 *inData = 0;
     FString inDataString = "NO DATA";
     int32 byteCount = 0;
     uint32 dataSize = 0;
 
     client->Send((uint8*)TCHAR_TO_UTF8(sendData), size, sent);
     GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Data away!"));
     client->HasPendingData(dataSize);
     if (dataSize != 0){
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, TEXT("Got something."));
         client->Recv(inData, dataSize, byteCount);
         GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::FromInt(byteCount));
     }
 }
 
 

I haven’t been able to get the data back from the server in UE4 but it works in the C# socket client I have. Any thoughts?

Cross-posted with permission from AnswerHub: FSocket->Recv no data response - Multiplayer & Networking - Epic Developer Community Forums

I am sorry to say i do not have a answer to your question, but as you seem to have more understanding of UE4s networking then i do at this moment, do you happen to know if the UE4 packets are encrypted at all?, or would we want to look into making our own solution for something as far as passing usernames/passwords around?, sorry if it seems like i am hijacking your thread, i just figured you might already have noticed something :slight_smile:

I’m working a nice editor tool that lets you integrate the engine with your external services easily, it will be in form of an OpenSource plugin. I can share two methods that are working quite nice for me. What I’m doing is to serialize the data to a string format (I use JSON/BSON as my internal protocol):

/**
 * Send a string to a given socket
 */
bool SendMsg(FSocket *Socket, const FString& Msg)
{
	check(Socket);
	int32 BytesSent = 0;
	return Socket->Send((uint8*)TCHAR_TO_UTF8(*Msg), Msg.Len(), BytesSent);
}

/**
* Recv a string from a given socket
*/
bool RecvMsg(FSocket *Socket, uint32 DataSize, FString& Msg)
{
	check(Socket);

	FArrayReaderPtr Datagram = MakeShareable(new FArrayReader(true));
	Datagram->Init(FMath::Min(DataSize, 65507u));

	int32 BytesRead = 0;
	if (Socket->Recv(Datagram->GetData(), Datagram->Num(), BytesRead))
	{
		char* Data = (char*)Datagram->GetData();
		Data[BytesRead] = '\0';
		Msg = UTF8_TO_TCHAR(Data);
		return true;
	}
	return false;
}

These two functions have a drawback, they do not account for network byte order (that’s what I’m fixing right now :D). You can use the htons method I guess. You should call the RecvMsg function with the DataSize you got from the HasPendingData method:


if ( Socket->hasPendingdata(DataSize) {
	FString Request;
	if (RecvMsg(Socket, DataSize, Request)
	{
		// Request contains the received data
	}
}

Hope I could help out ^^

Cheers,
Moss

That is one the ideas that we have thought about, but don’t have much time for right now. We have already set-up a server that accepts data from clients and attempts to shoot back data, but the clients seem to not be accepting the returning data. We have no idea what is going as, as we built an implementation outside of Unreal doing the same thing and it works correctly, but once implemented inside Unreal, it stops working.

One of my engineers thinks it could possibly be a bug in Unreal’s FSocket?

I’m talking with a python server so that is strange

But over UDP instead of TCP

Hmm, after seeing this post, we tried moving things from TCP to UDP, but we still having the same issue. Unreal does not want to accept the incoming data. :expressionless:

Hey everyone,

I run into the same problem and it doesn’t seem to have been answered yet.

The client sends a messages to a file server and waits for a response.

The message is well received by the server, but its response is never received by the client.

Here is my code:


file server side:

// the incoming message is received and when everything is ok, bIsMessageOK is set to true
// so the server sends back a response:
if (bIsMessageOK)
{
	TCHAR *ResponseChar = TEXT("ACK");
	int32 sent = 0;

	ConnectionSocket->Send((uint8*)TCHAR_TO_UTF8(ResponseChar), UYagFileServer::VerbSize, sent);

	GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red, FString::Printf(TEXT("ACK sent")));
}

--------------------------------------------------------------------------------------------------------

client side:

// if the message is sent correctly, then start listening to a response
if (ConnectionSocket->Send((uint8*)TCHAR_TO_UTF8(ThisMessageChar), MessageSize, MessageSent))
{
	FTimerHandle ListenToResponseTimerHandle;
	GetWorld()->GetTimerManager().SetTimer(ListenToResponseTimerHandle, this, &AYagActor::ListenToResponse, 0.5f, true);
}

void AYagActor::ListenToResponse()
{
	TArray<uint8> ReceivedData;
	uint32 Size;

	while (ConnectionSocket->HasPendingData(Size))
	{
		ReceivedData.Init(UYagFileServer::VerbSize);
		int32 SizeRead = 0;

		ConnectionSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), SizeRead);
	}

	if (ReceivedData.Num() > 0)
	{
		GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red, TEXT("Response received"));
	}
}


I get the “ack sent” message, but never the “response received” one.

I have no experience in network programming so i am not even sure this is the right way to proceed.

Any help welcome^^

Cheers

Cedric

I’ve added some tests in the listening delegate:


void AYagActor::ListenToResponse()
{
	if (ConnectionSocket->GetConnectionState() == ESocketConnectionState::SCS_Connected) GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red, FString::Printf(TEXT("CLIENT CONNECTED")));
	if (ConnectionSocket->GetConnectionState() == ESocketConnectionState::SCS_NotConnected) GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red, FString::Printf(TEXT("CLIENT NOT CONNECTED")));
	if (ConnectionSocket->GetConnectionState() == ESocketConnectionState::SCS_ConnectionError) GEngine->AddOnScreenDebugMessage(-1, 30.f, FColor::Red, FString::Printf(TEXT("CLIENT CONNECTION ERROR")));

// rest of the code
	...]
}

This gives me the “connection error” message.

So no wonder i don’t get any response inside this delegate.

In any other function than this delegate, the socket is connected but i can’t wait for the message to arrive.

I tried to get rid of the timer and use instead the wait() function in blocking mode (with a time out) but it displays no message during its waiting period (and i still get no response during or after the wait call).

  • is there something special with timer/delegates and sockets ? i don’t know how timers work, is it possible that the (class variable) ConnectionSocket is unknown to the delegate ?
  • is there a way to get a more precise error code ?

Thanks

Cedric

facepalm

I was closing the socket in another function, isn’t that clever ? :smiley:

It works very well now, sorry for the intrusion^^

Cheers

Cedric

@uced, so your’s is working unlike the OP? What is the difference?

I can’t tell.

The code i posted is basically the one that works (my mistake was elsewhere), so you know as much as i do.

One difference between my (pseudo) problem and the original post problem is that in my case, ue4 is connected to ue4, i connect an FSocket to another FSocket, while in the original post, it seems that the FSocket is connected to a non-ue4 socket.

I have no idea of how that would make a difference, but i’ve nothing else on top on my head.

Cedric

Hmm… that is interesting. Considering if we want to make a ‘master server’ for a game, odds are it’s just going to be a server and not UE4 at all… Will have to add it to my list of things to play with.

One way to go would be to have a look on the FSocket code, see how it encapsulates regular C sockets (supposing it does and wasn’t rewritten from scratch).

A little bit beyond my present c++ skills i’m afraid, but if you’re gonna dig this issue, you might want to think about this direction.

Cheers