我有2台电脑:我称之为Comp A,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 所以这是我的程序代码。我使用定时器功能每秒发送每秒800 Kb,每秒调用2次。
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();
}
如果我在没有定时器或任何循环(同时等)的情况下调用函数m_pUdpServer.SendPacket(buffer, 0, Convert.ToInt32(bytes_count), m_pTargetEP);
,我会在输出中看到正确的结果。
这里是120 - 在每个定时器函数调用期间传输的许多文件部分。定时器功能每秒调用2次。
BUFFERSIZE
是一个总文件大小。ReadBuffer
是一个包含所有PCM文件数据的数组。 RAW PACKET
= 400字节。 sent_data
是在每个定时器函数调用中发送的总字节数。 num
是已发送数据包的总数。 我想在定时器函数调用中发送的包(字节)太多了。因此,我看到输出值不正确。
那么这个问题的解决方案是什么?
我想我可以组成一个RTP数据包(为每个发送的数据包添加一个序列号)。它将帮助我识别收到的数据包并组成正确的接收数据包序列。如果收到的数据包具有正确的字节序列,它可以帮助我。因为如果接收的数据包具有混合的字节顺序(序列),我不明白如何在每个接收的数据包中恢复正确的字节序列。
我被建议拒绝定时器调用并均匀地使用同步时间发送数据包。其实我不知道怎么做。也许我应该使用线程,线程池或类似的东西。你怎么看?
答案 0 :(得分:1)
UDP为您提供的唯一保证是整个邮件的传递。但是,如果您按顺序发送1,2,3,4,则可以按任何顺序接收它们,例如4132.也就是说,UDP不保证订购。
您必须包含序列号才能正确存储PCM。
UDP也不保证交付。如果服务器在X秒内收到#4而不是#5,它可能会再次请求该作品。
或者您只是切换到TCP。更容易。您只需要一些方法来判断文件的长度,然后转移它。