Hi to all,
I’m trying to receive a message containing some data from a local server and use these to update the position of some objects into Unreal. The problem is that the packets correctly arrives to my machine but for some reasons Unreal only receives the first one, prints his size (with seems too big) and then stops receiving. The message sent is built as a string that should then be fetched to get back values using sscanf by UE. Any suggestion?
UE Receiving code:
// Initialize the communication
bool UUDP_Component::StartUDPComm(const FString& YourChosenSocketName)
{
ScreenMsg("SOCKETS INIT");
ScreenMsg("Source IP = ", SourceIP_Address);
ScreenMsg("Source Port = ", PortIn);
ScreenMsg("Destination IP = ", DestIP_Address);
ScreenMsg("Destination Port = ", PortOut);
FIPv4Address SourceAddr, DestAddr;
// Parse the IP addresses
FIPv4Address::Parse(SourceIP_Address, SourceAddr);
FIPv4Address::Parse(DestIP_Address, DestAddr);
// Create the endpoint object
FIPv4Endpoint InputEndpoint(SourceAddr, PortIn);
FIPv4Endpoint OutputEndpoint(DestAddr, PortOut);
bool valid = false;
RemoteAddr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
RemoteAddr->SetIp(*DestIP_Address, valid);
RemoteAddr->SetPort(PortOut);
if (!valid)
{
ScreenMsg("Problem with the remote Address!");
return false;
}
// BUFFER SIZE
int32 BufferSize = 2 * 1024 * 1024;
//Create Listener Socket
ListenSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsNonBlocking()
.AsReusable()
.BoundToEndpoint(InputEndpoint)
.WithReceiveBufferSize(BufferSize);
// Create Sender Socket
SendSocket = FUdpSocketBuilder(*YourChosenSocketName)
.AsReusable()
.WithSendBufferSize(BufferSize)
.WithBroadcast();
// Spaw a receiving thread
FTimespan ThreadWaitTime = FTimespan::FromMilliseconds(4);
UDPReceiver = new FUdpSocketReceiver(ListenSocket, ThreadWaitTime, TEXT("UDP RECEIVER"));
UDPReceiver->OnDataReceived().BindUObject(this, &UUDP_Component::Recv);
ScreenMsg("Starting Listening Thread...");
UDPReceiver->Start();
return true;
}
////////////////////////////////////////
// FUNCTIONS
////////////////////////////////////////
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
* Receiving Part
* The receiving thread calls this function, which copy the data in the class variable
* DataIn.
*/
void UUDP_Component::Recv(const FArrayReaderPtr& ArrayReaderPtr, const FIPv4Endpoint& EndPt)
{
ScreenMsg("Received bytes", ArrayReaderPtr->Num());
//ArrayReaderPtr->Serialize(DataIn.GetData(), ArrayReaderPtr->Num());
FString data;
*ArrayReaderPtr >> data;
ScreenMsg("Received: ", data);
std::sscanf(TCHAR_TO_ANSI(*data), "(%f, %f, %f), (%f, %f, %f), (%f, %f, %f)", &DataIn.drone_X, &DataIn.drone_Y, &DataIn.drone_Z, &DataIn.drone_Roll, &DataIn.drone_Pitch, &DataIn.drone_Yaw, &DataIn.ball_X, &DataIn.ball_Y, &DataIn.ball_Z);
ScreenMsg("Received X: ", DataIn.drone_X);
//*ArrayReaderPtr << DataIn;
}
Server send code:
int port_open(int port){
int sfd, res;
struct sockaddr_in myaddr;
sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd < 0){
perror("can't create UDP socket");
return -1;
}
memset((char *)&myaddr, 0, sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_addr.s_addr = htonl(INADDR_ANY); //Set ip address bind the socket to
myaddr.sin_port = htons(port); //Set the port
res = bind(sfd, (struct sockaddr *)&myaddr, sizeof(myaddr));
if(res < 0){
perror("can't bind socket");
return -1;
}
return sfd;
}
int UDP_connect(int sfd, char *dst_ip_addr, unsigned short dst_port){
struct sockaddr_in dest;
memset(&dest, 0, sizeof(dest));
dest.sin_family = DOMAIN;
dest.sin_port = htons(dst_port);
inet_pton(AF_INET, dst_ip_addr, &dest.sin_addr);
return connect(sfd, (struct sockaddr*)&dest, sizeof(dest));
}
/*
Converts the struct containing enviroment info into a char message that can be sent through the network
struct udp_graph *env: structure containing data to send
char *message: pointer to the buffer that will contain the message to send
*/
void serialize(struct udp_graph *env, char *message){
int len;
len = sprintf(message, "(%9.3f, %9.3f, %9.3f), (%9.3f, %9.3f, %9.3f), (%9.3f, %9.3f, %9.3f)", env->drone_pos[0], env->drone_pos[1], env->drone_pos[2], env->drone_ang[0], env->drone_ang[1], env->drone_ang[2], env->ball_pos[0], env->ball_pos[1], env->ball_pos[2]);
printf("len: %d
", len);
sleep(1);
}
//TASK TO SEND POSITION UPDATES TO UE
void *UDP_send_task(void *arg){
struct udp_graph enviroment;
int sfd;
int res;
char message[128];
sfd = port_open(10100); //Create the socket
UDP_connect(sfd, DST_ADDR, DST_PORT); //Connect to the recipient
enviroment.drone_pos[0] = 200.0f;
enviroment.drone_pos[1] = 0.0f;
enviroment.drone_pos[2] = 0.0f;
enviroment.drone_ang[0] = 0.0f;
enviroment.drone_ang[1] = 0.0f;
enviroment.drone_ang[2] = 0.0f;
enviroment.ball_pos[0] = 0.0f;
enviroment.ball_pos[1] = 0.0f;
enviroment.ball_pos[2] = 0.0f;
while(!end){
serialize(&enviroment, message);
res = send(sfd, message, sizeof(struct udp_graph), 0); //Send data
sleep(1); //TODO: improve
//printf("End sleep
");
}
close(sfd);
}