【UE4】 第12讲 FSocket断线重连

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nanhu2012/article/details/71273232

(版权声明,禁止转载)

【第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);

	}
}

猜你喜欢

转载自blog.csdn.net/Nanhu2012/article/details/71273232