UE C++ FUdpSender和FUdpReveiver

	FUdpSender和FUdpReceiver提供了一种更加便捷的方式来进行UDP消息的收发。

UdpSender

class FUdpSocketSender
	: public FRunnable
	, private FSingleThreadRunnable

FUdpSender继承于FRunnale和FSiungleThreadRunnable。

每次要发送的数据被封装成了一个包,如下结构。

	// Structure for outbound packets.
	struct FPacket
	{
		/** Holds the packet's data. */
		TSharedPtr<TArray<uint8>, ESPMode::ThreadSafe> Data;

		/** Holds the recipient. */
		FIPv4Endpoint Recipient;

		/** Default constructor. */
		FPacket() { }

		/** Creates and initializes a new instance. */
		FPacket(const TSharedRef<TArray<uint8>, ESPMode::ThreadSafe>& InData, const FIPv4Endpoint& InRecipient)
			: Data(InData)
			, Recipient(InRecipient)
		{ }
	};

因为涉及到多线程访问数据,所以使用TSharedRef和TSharedPtr的线程安全版本。另外使用 IPv4Endpoint记录了一个要发送的目标socket地址。

发送一个包:

	/**
	 * Sends data to the specified recipient.
	 *
	 * @param Data The data to send.
	 * @param Recipient The recipient.
	 * @return true if the data will be sent, false otherwise.
	 */
	bool Send(const TSharedRef<TArray<uint8>, ESPMode::ThreadSafe>& Data, const FIPv4Endpoint& Recipient)
	{
		if (!Stopping && SendQueue.Enqueue(FPacket(Data, Recipient)))
		{
			WorkEvent->Trigger();

			return true;
		}

		return false;
	}
	/**
	 * Creates and initializes a new socket sender.
	 *
	 * @param InSocket The UDP socket to use for sending data.
	 * @param ThreadDescription The thread description text (for debugging).
	 */
	FUdpSocketSender(FSocket* InSocket, const TCHAR* ThreadDescription)
		: SendRate(0)
		, Socket(InSocket)
		, Stopping(false)
		, WaitTime(FTimespan::FromMilliseconds(100))
	{
		check(Socket != nullptr);
		check(Socket->GetSocketType() == SOCKTYPE_Datagram);

		int32 NewSize = 0;
		Socket->SetSendBufferSize(512 * 1024, NewSize);

		WorkEvent = FPlatformProcess::GetSynchEventFromPool();
		Thread = FRunnableThread::Create(this, ThreadDescription, 128 * 1024, TPri_AboveNormal, FPlatformAffinity::GetPoolThreadMask()); //创建线程
	}

可以看见FUdpSender使用了多线程+消息队列来处理要发送的消息。注意接口使用的是const TSharedRef<TArray<uint8>而不是uint8*目的是为了保证线程安全。

UdpReciver

FUdpReveiver同样继承于FRunnale和FSiungleThreadRunnable。

class FUdpSocketReceiver
	: public FRunnable
	, private FSingleThreadRunnable

接受消息

	/**
	 * Returns a delegate that is executed when data has been received.
	 *
	 * This delegate must be bound before the receiver thread is started with
	 * the Start() method. It cannot be unbound while the thread is running.
	 *
	 * @return The delegate.
	 */
	FOnSocketDataReceived& OnDataReceived()
	{
		check(Thread == nullptr);
		return DataReceivedDelegate;
	}

使用OnDataReceived返回一个可接受两个参数的单播委托。通过对这个委托进行绑定,可完成对接受数据的处理。

/**
 * Delegate type for received data.
 *
 * The first parameter is the received data.
 * The second parameter is sender's IP endpoint.
 */
DECLARE_DELEGATE_TwoParams(FOnSocketDataReceived, const FArrayReaderPtr&, const FIPv4Endpoint&);

第一个参数是收到到的数据,第二个参数是发送者的地址。其中FArrayReaderPtr是一个typedef

/**
 * Temporary fix for concurrency crashes. This whole class will be redesigned.
 */
typedef TSharedPtr<FArrayReader, ESPMode::ThreadSafe> FArrayReaderPtr;
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值