2

我正在开发一个 WP8 项目,该项目应该通过 UDP 将数据传输到连接的应用程序(WP8 也是)。我决定使用 DatagramSocket 来与 Windows 8 共享代码。

服务器和客户端应用程序可以相互连接。在客户端连接到服务器后,它会发送一个命令,该命令应该相应地回答服务器。客户端连接和命令发送代码如下:

var stream = await _udpSocket.GetOutputStreamAsync(server, UdpCommunication.Port);
var writer = new DataWriter(stream);
writer.UnicodeEncoding = UnicodeEncoding.Utf8;

uint messageSize = writer.MeasureString(UdpCommunication.ReceiveImageCommand);
writer.WriteUInt32(messageSize);
await writer.StoreAsync();

writer.WriteString(UdpCommunication.ReceiveImageCommand);
await writer.StoreAsync();
await writer.FlushAsync();

因此,我将传输消息大小,然后传输字符串命令名称。到目前为止,一切都很好。

服务器从 DatagramSocket 接收 MessageReceived 事件,我让 DataReader 和 trz 读取 4 bztes。在调用它的过程中,我收到以下异常消息:“操作标识符无效。” (结果-2147020579)

MessageReceived 事件的代码:

DataReader reader = args.GetDataReader();
reader.UnicodeEncoding = UnicodeEncoding.Utf8;

await reader.LoadAsync(4);
uint messageSize = reader.ReadUInt32();

await reader.LoadAsync(messageSize);
string message = reader.ReadString(messageSize);

有没有人知道为什么会抛出这个异常以及如何解决它?我已经完成了 TCP、蓝牙和 NFC,并且都在工作并且有类似的代码。但是UDP让我发疯了......

感谢您的时间和帮助!

4

2 回答 2

2

你不应该调用LoadAsync从调用DataReader返回的DatagramSocketMessageReceivedEventArgs.GetDataReader()。似乎数据报已经在那里加载了。如果你检查UnconsumedBufferLength那个阅读器,你会看到它包含你的数据报的完整大小。

实际上,这对于 UDP 套接字是有意义的,因为在 WinSock 库(我猜,这是 WinRT 套接字的底层实现)中,您总是在一次recvfrom调用中接收到整个数据报(如果您为它提供了足够大的缓冲区,但我希望 WinRT 为我们处理这个问题)。无需异步读取流 - 您的所有数据都已经存在。

因此,请继续从该流中读取您的值。您的代码将转换为:

DataReader reader = args.GetDataReader();
reader.UnicodeEncoding = UnicodeEncoding.Utf8;
uint messageSize = reader.ReadUInt32();
string message = reader.ReadString(messageSize);
于 2013-04-18T19:32:22.843 回答
0

实际上,尽管您随代码一起提供了正确答案,但上面的代码不起作用。以下是如何让它工作:

var reader = args.GetDataReader();
reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
var size = reader.UnconsumedBufferLength;
var message = reader.ReadString(size);
于 2013-08-04T09:47:45.843 回答