【发布时间】:2016-04-26 00:24:09
【问题描述】:
我有 2 台电脑:我会称它们为 Comp A、Comp B;
我必须:
- 将 PCM 格式的声音文件从 Comp А 发送到 Comp B;
- 验证此文件的传输精度;
- 在 Comp B 上播放我发送给 Comp B 的内容。
要发送文件,我使用函数
socket.SendTo(packet,0,count,SocketFlags.None,remoteEP);
来自System.Net.Sockets。
因此,我得出结论,文件正在准确传输。我在 Comp A 和 Comp B 上使用 Wireshark 对其进行监控。但是,到达 Comp B 的字节包与正在传输的文件完全不一致。
发送文件数据的程序,以正确的方式打开这个文件。然后它将源 PCM 文件的右字节传递给函数Socket.SendTo(...)。但是 Comp A(输出)的 Wireshark 显示绝对不正确的字节,即 Comp A 发送的字节不正确。
可能是什么问题?
我发现了那个函数socket.SendTo(packet,0,count,SocketFlags.None,remoteEP);
如果我延迟发送它们,则发送正确的字节。我的意思是我可以发送 400 个字节(没有循环),我的程序发送 400 个绝对精确、正确的字节。
但是我有一个很大的 PCM 文件。它的大小约为 50 Mb。其持续时间为 1 分钟。我必须在一分钟内发送这个文件,以便这个文件被均匀、统一地传输。这意味着每秒需要传输大约 800 Kb。
所以这是我的程序代码。我使用每秒调用 2 次的定时器函数每秒发送 800 Kb。
private void m_pTimer_Tick(object sender,EventArgs e)
{
uint sent_data = 0;
while ((sent_data <= (BUFFERSIZE / 120)) && ((num * RAW_PACKET) + sent_data < BUFFERSIZE))
{
uint bytes_count = ((BUFFERSIZE - (RAW_PACKET * num)) > RAW_PACKET) ? RAW_PACKET : (BUFFERSIZE - (RAW_PACKET * num));
byte[] buffer = new byte[bytes_count];
Array.Copy(ReadBuffer, num * RAW_PACKET, buffer, 0, bytes_count);
num++;
// Send and read next.
m_pUdpServer.SendPacket(buffer, 0, Convert.ToInt32(bytes_count), m_pTargetEP);
sent_data += bytes_count;
}
if ((num * RAW_PACKET) + sent_data == BUFFERSIZE)
{
m_pTimer.Enabled = false;
}
m_pPacketsReceived.Text = m_pUdpServer.PacketsReceived.ToString();
m_pBytesReceived.Text = m_pUdpServer.BytesReceived.ToString();
m_pPacketsSent.Text = m_pUdpServer.PacketsSent.ToString();
m_pBytesSent.Text = m_pUdpServer.BytesSent.ToString();
}
如果我在没有计时器或任何循环(while 等)的情况下调用函数 m_pUdpServer.SendPacket(buffer, 0, Convert.ToInt32(bytes_count), m_pTargetEP);,我会在输出中看到正确的结果。
这里是 120 - 在每个计时器函数调用的一段时间内传输的文件部分的数量。定时器函数每秒调用 2 次。
-
BUFFERSIZE是总文件大小。 -
ReadBuffer是一个包含所有 PCM 文件数据的数组。 -
RAW PACKET= 400 字节。 -
sent_data是在每个定时器函数调用中发送的总字节数。 -
num是发送数据包的总数。
我想在定时器函数调用中发送的数据包(字节)太多。因此,我在输出中看到不正确的值。
那么解决这个问题的方法是什么?
我想我可以组成一个 RTP 数据包(为每个发送的数据包添加一个序列号)。它将帮助我识别接收到的数据包并组成正确的接收数据包序列。如果收到的数据包具有正确的字节序列,它可以帮助我。因为如果接收到的数据包具有混合字节顺序(序列),我不明白如何在每个接收到的数据包中恢复正确的字节序列。
我被建议拒绝计时器调用并均匀发送数据包,统一使用时间同步。其实我不知道该怎么做。也许我应该使用线程、线程池或类似的东西。你怎么看?
【问题讨论】:
-
SendTo发送的字节数可能少于count字节,按设计。 -
....这就是为什么它返回 de
sent bytescount -
在wireshark上看到trame时要小心字节序
-
不,如果我交换位置字节,我看不到类似的东西
-
API 没问题。套接字准确地发送和接收您告诉它们的字节。如果您认为他们没有这样做,那么要么您将错误的字节传递给了 send 方法,要么没有正确处理您收到的字节。缺少一个好的minimal reproducible example 是不可能告诉你你做错了什么。哎呀,你甚至没有告诉我们这是 TCP 还是 UDP(
SendTo()通常表示 UDP,但许多 .wav 文件太大而无法放入单个 UDP 数据报)。