【UE4】 第12講 FSocket斷線重連
阿新 • • 發佈:2018-11-12
(版權宣告,禁止轉載)
【第03講】 實現了FSocket的連網基礎功能,這一講實現一下 斷線重連
<如果資深前輩發現有理解錯誤,還請不吝指正>
<1> 建立Socket,設定阻塞模式(預設創建出來的就是阻塞模式,不用設定)
void ANetwork::BeginPlay() { Super::BeginPlay(); Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false); // Socket->SetNonBlocking(); //... }
<2>對網路地址成員變數的儲存方式做個調整,從指標改為TSharedPtr,這樣保證只需建立一次
class ANetwork { // ... static TSharedPtr<class FInternetAddr> InetAddr; //... }; void ANetwork::BeginPlay() { //... FString address = TEXT("119.23.171.163"); int32 port = 8888; FIPv4Address ip; FIPv4Address::Parse(address, ip); TSharedRef<FInternetAddr> addr = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateInternetAddr(); addr->SetIp(ip.Value); addr->SetPort(port); InetAddr = addr; }
<3>Connect成功之後,設定為非阻塞模式
bool ANetwork::Connect() { if (Socket && !Connected) { Connected = Socket->Connect(*InetAddr); if(Connected) Socket->SetNonBlocking(); else { FPlatformProcess::Sleep(1); } } return Connected; }
<4>Recv檢測到連線斷開,重新建立Socket
void ANetwork::Recv()
{
if(Socket)
Connected = Socket->Recv(ptr, 2, BytesRead);
if (!Connected)
{
Socket->Close();
ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->DestroySocket(Socket);
Socket = ISocketSubsystem::Get(PLATFORM_SOCKETSUBSYSTEM)->CreateSocket(NAME_Stream, TEXT("default"), false);
// Socket->SetNonBlocking();
}
}
<5> 如果斷開,EventLoop迴圈Connect
void ANetwork::EventLoop(void* data)
{
while (1)
{
if (!Socket || bGameOver)
{
Close();
break;
}
if (!Connected)
Connect();
if (Connected)
Recv();
FPlatformProcess::Sleep(0.03);
}
}