udp 视频包网络传输花屏

    视频数据传输在传输层可以选择TCP或者UDPTCP面向连接,传输中断,发送端是知道的。TCP传输的好处是不丢包,坏处是网络不太好的情况下会越堵越严重。UDP非面向连接,发送端只管发送数据,接收端有没有接收到不管。UDP的好处应该是实时性,坏处显而易见:网络抖动大时数据会丢失严重,出现我们常说的花屏的情况。有一些情况是网络也“正常”,ping包延时很低。但是接收端也会出现花屏。这是什为何呢?下面我将讲述这种情况如何解决。

      如果视频发送端视频数据播放正常,接收端播放视频花屏,第一件事情就是WireShark抓包。WireShark会告诉你很多问题点。有一种情况是发送端每次发送的数据包过大。一般交换机MTU单元设置一次通过的数据包大小是1500字节。如果WireShark显示很多fragment(分片)说明数据包被拆分。两种解决方案,要么增大MTU值,要么重新组包,保证数据包的大小在MTU范围内。正常情况下,要求网络工程师设置通用值1500字节。因为很多库比如Ffmpeg就遵守这个值。在实际的项目中我就遇到过接收端播放视频花屏,怎么修改代码都没有,最后定位的数据包的网络传输,让网络工程师修改MTU,问题才得以解决。

    包大了不行,小了同样也会有问题。这个问题是本文的另一作者皑雪发现并解决的,问题是单个数据包太小接收端播放视频同样出现花屏,我所遇到的网络环境里没有碰到这种情况数据包小了,多发几次也没出现花屏。这个问题的解决方法是如果包太小先缓存,等数据包够数时一起发送。下面给出解决问题的基本代码(代码是皑雪写的)。

#define BUFFER_LEN   1480

if (m_nBufferLen + nDataSize < BUFFER_LEN)

{

memcpy(m_pchBuffer + m_nBufferLen, (char*)pkt + RTP_HEAD_LEN, nDataSize);

m_nBufferLen += nDataSize;

}

else

{

SendData(pthis->sendtransport, m_pchBuffer, m_nBufferLen);

 memset(m_pchBuffer, 0, sizeof(m_pchBuffer));

m_nBufferLen = 0;

memcpy(m_pchBuffer, (char*)pkt + RTP_HEAD_LEN, nDataSize);

m_nBufferLen = nDataSize;

}

转载于:https://my.oschina.net/u/3700450/blog/1545627

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Unity是一款跨平台的游戏引擎,提供了丰富的功能和工具,可以方便地接收UDP数据。接收UDP数据的过程需要使用Unity的Network类以及网络连接组件。下面是一个简单的示例代码,展示了如何在Unity中接收UDP数据: ``` using UnityEngine; using System.Net; using System.Net.Sockets; using System.Text; public class UDPReceiver : MonoBehaviour { private UdpClient udpClient; private int port = 8888; void Start() { udpClient = new UdpClient(port); udpClient.BeginReceive(ReceiveCallback, null); } void Update() { // 在Update方法中可以处理接收到的数据 } private void ReceiveCallback(IAsyncResult result) { if (udpClient != null) { IPEndPoint remoteEndPoint = null; byte[] receivedData = udpClient.EndReceive(result, ref remoteEndPoint); // 处理接收到的数据,这里以字符串为例 string receivedMessage = Encoding.UTF8.GetString(receivedData); Debug.Log("Received: " + receivedMessage); // 接收下一条数据 udpClient.BeginReceive(ReceiveCallback, null); } } void OnApplicationQuit() { // 停止接收数据并关闭UDP客户端 if (udpClient != null) { udpClient.Close(); } } } ``` 在该示例中,首先创建了一个UdpClient对象并指定监听的端口号。在Start方法中,使用udpClient.BeginReceive方法开始异步接收UDP数据,并提供一个回调函数ReceiveCallback用于处理接收到的数据。在ReceiveCallback回调函数中,解析接收到的数据并进行处理,这里使用了Debug.Log输出接收到的消息。然后再次调用udpClient.BeginReceive方法,接收下一条数据。 在Update方法中,可以实时处理接收到的数据。最后,为了确保在应用程序退出时正确关闭UDP客户端,我们在OnApplicationQuit方法中手动关闭了udpClient。 总结来说,Unity接收UDP数据需要创建UdpClient对象,并使用BeginReceive方法开始异步接收数据,通过回调函数处理接收到的数据。这样就可以方便地在Unity中接收UDP数据了。 ### 回答2: Unity可以通过使用Socket类来接收UDP数据。以下是一个简单的示例代码。 首先,在Unity中创建一个新的C#脚本,命名为UDPReceiver。在脚本中,引入System.Net.Sockets和System.Text命名空间。 ```csharp using System.Net.Sockets; using System.Text; ``` 接下来,在UDPReceiver脚本中创建一个UDP客户端Socket实例,并指定要使用的本地IP地址和端口号。 ```csharp UdpClient udpClient = new UdpClient("127.0.0.1", 1234); ``` 然后,在Start()函数中,创建一个异步接收器,以接收UDP数据。 ```csharp void Start() { udpClient.BeginReceive(ReceiveCallback, null); } ``` 在ReceiveCallback回调函数中,接收UDP数据,并将其转换为字符串。 ```csharp void ReceiveCallback(IAsyncResult result) { IPEndPoint source = new IPEndPoint(IPAddress.Any, 0); byte[] receivedBytes = udpClient.EndReceive(result, ref source); string receivedString = Encoding.ASCII.GetString(receivedBytes); // 处理接收到的数据 Debug.Log("Received data: " + receivedString); // 继续异步接收下一个数据 udpClient.BeginReceive(ReceiveCallback, null); } ``` 最后,在Update()函数中,可以根据需要处理接收到的数据。 ```csharp void Update() { // 进行其他逻辑处理 } ``` 完成以上步骤后,您可以将UDPReceiver脚本附加到Unity场景中的游戏对象上,然后运行场景。Unity将开始接收来自指定IP地址和端口号的UDP数据,并在控制台窗口中打印接收到的数据。您可以根据自己的需求修改和扩展此示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值