我一直在研究一些代码,它允许我通过 UDP 从我的游戏引擎(Unity)共享屏幕到我的安卓手机。
该过程实际上只是截取屏幕截图,将它们解码为 jpeg 字节数组并将这些字节数组拆分为多个包(如果需要)。
当我运行该项目时,它实际上是在发送图像,但有些图像在接收时会失真或混乱。
所以我对缓冲区大小进行了一些调整,我注意到增加接收 UDP 客户端的缓冲区大小实际上改善了数据丢失/损坏。但不幸的是,仍然有太多用户无法忽略的损坏数据。
过了一会儿,主机(我的手机)就崩溃了。我认为这与包缓冲区大小有关,也许它被淹没了?
无论如何,这是处理连接的一段代码。我目前只以一种方式发送数据(计算机 - >手机),但它已设置为将其他信息从我的手机发送到我的计算机(但这是为了以后,我需要先让它工作)。
public void OpenConnection(string hostname, int bufferSize, int port = 12005)
{
ep1 = new IPEndPoint(IPAddress.Any, port);
receiveThread = new Thread(new ThreadStart((delegate
{
receiveClient = new UdpClient();
receiveClient.Client.ReceiveBufferSize = bufferSize;
receiveClient.ExclusiveAddressUse = false;
receiveClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
receiveClient.Client.Bind(ep1);
while(true)
{
try
{
byte[] buffer = receiveClient.Receive(ref ep1);
if(buffer != null && onDataReceived != null) onDataReceived(buffer);
}
catch(Exception ex)
{
Debug.Log("Error: " + ex.ToString());
}
}
})));
sendClient = new UdpClient();
sendClient.Client.SendBufferSize = bufferSize;
sendClient.ExclusiveAddressUse = false;
sendClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
ep2 = new IPEndPoint(IPAddress.Parse(hostname), port);
sendClient.Client.Bind(ep1);
receiveThread.Start();
}
public void SendData(byte[] data)
{
if(sendClient != null){
try
{
sendClient.Send(data, data.Length, ep2);
}
catch(Exception ex)
{
Debug.Log("error: " + ex.ToString());
}
}
}
目前我将变量bufferSize
设置为20.000
,切片图像数据包是序列化类(带有帧 ID、包 ID、图像数据等),总大小为15.200
ish。
我知道 UDP 的后果,但我真的需要尽可能低的延迟。我应该切换到 TCP 吗?现在的图像大小只是在测试蓝色背景上有一些粒子的立方体的图像。我认为当传输更复杂的图像时,JPEG 压缩文件也会增加。
谢谢!