When my client disconnects from the server, Unreal never seems to recognize that the disconnect happened in Windows (I have not tried in Linux). It seems like the following conditional should return false when a client disconnects, but this function never returns anything other than SCS_Connected.
ClientSocket->GetConnectionState() == ESocketConnectionState::SCS_Connected
Cobbling together what few examples I can find on FSocket, this is my code below. It successfully detects the client, and receives data, but cannot detect a client disconnect.
Setting up the server socket:
Socket = TSharedPtr<FSocket, ESPMode::ThreadSafe>(ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("SimulatorSocket"), false));
FIPv4Address ip;
FIPv4Address::Parse(address, ip);
TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
addr->SetIp(ip.GetValue());
addr->SetPort(port);
Socket->SetReuseAddr(true);
Socket->Bind(*addr);
Socket->Listen(1);
Listening loop:
TArray<uint8> ReceivedData;
int32 byteCount = 0;
uint32 Size = 0;
bool pending = false;
while (Server->IsRunning()){
while (Server->IsRunning() && Server->Socket->HasPendingConnection(pending) && pending) {
UE_LOG(LogTemp, Warning, TEXT("Client detected"));
TSharedRef<FInternetAddr> RemoteAddress = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr();
TSharedPtr<FSocket> ClientSocket = TSharedPtr<FSocket>(Server->Socket->Accept(*RemoteAddress, TEXT("HolodeckServerClient")));
while (Server->IsRunning() && ClientSocket.IsValid() && ClientSocket->GetConnectionState() == ESocketConnectionState::SCS_Connected) {
if (ClientSocket->HasPendingData(Size)) {
ReceivedData.SetNumUninitialized(Size); //FMath::Min(Size, 65507u)
if (ClientSocket->Recv(ReceivedData.GetData(), ReceivedData.Num(), byteCount)) {
UE_LOG(LogTemp, Warning, TEXT("Success!"));
// TODO: Parse the data, create a message, publish
// Server->Publish(new FHolodeckCommand(.5));
}
else {
// Error receiving data, closing the client socket as a precaution
ClientSocket->Close();
}
}
}
if (ClientSocket.IsValid()) {
UE_LOG(LogTemp, Warning, TEXT("Disconnected from client!"));
ClientSocket->Close();
//ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(ClientSocket.Get());
UE_LOG(LogTemp, Warning, TEXT("Closed Socket!"));
}
}
}