使用DatagramSocket从SocketActivityTriggerDetails获取数据

时间:2016-11-22 14:37:52

标签: c# sockets uwp

MSDN的示例中,我尝试使用套接字代理和 SocketActivityTrigger 在后台任务中从 DatagramSocket 中检索接收的数据。 / p>

但链接中显示的示例是 StreamSocket

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var details = taskInstance.TriggerDetails as SocketActivityTriggerDetails;
    var socketInformation = details.SocketInformation;
    switch (details.Reason)
    {
        case SocketActivityTriggerReason.SocketActivity:
            var socket = socketInformation.StreamSocket; 
            DataReader reader = new DataReader(socket.InputStream); 
            reader.InputStreamOptions = InputStreamOptions.Partial; 
            await reader.LoadAsync(250); 
            var dataString = reader.ReadString(reader.UnconsumedBufferLength);
            break;
    }
}

我无法从DatagramSocket对象中找到收到的数据,我们只能访问输出流..

我该怎么办?

谢谢!

3 个答案:

答案 0 :(得分:0)

  

我无法从DatagramSocket对象中找到收到的数据,我们只能访问输出流..

对于DatagramSocket对象,当我们需要接收数据时,我们需要最适合注册其MessageReceived event,然后在其DatagramSocketMessageReceivedEventArgs中,我们可以使用其GetDataReader method来获取传输的数据。

对于后台任务,代码类似于official Socket activity trigger stream socket sample。但是对于DatagramSocket,我们需要注册此MessageReceived事件并处理后台任务中的数据。

仅举例来说:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();
    try
    {
        var details = taskInstance.TriggerDetails as SocketActivityTriggerDetails;
        var socketInformation = details.SocketInformation;
        switch (details.Reason)
        {
            case SocketActivityTriggerReason.SocketActivity:
                var socket = socketInformation.DatagramSocket;
                socket.MessageReceived += Socket_MessageReceived;
                break;
            default:
                break;
        }
        deferral.Complete();
    }
    catch (Exception exception)
    {
        ShowToast(exception.Message);
        deferral.Complete();
    }
}

private void Socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    using (var reader = args.GetDataReader())
    {
        //TODO: read data here.
    }
}

答案 1 :(得分:0)

您必须在bindServiceName或bindEndPoint之后调用EnableOwnerShip,TransferOwnerShip方法。我现在在这个主题上工作..

答案 2 :(得分:0)

@ grace-feng-mst的答案是准确的。完成操作后,DatagramSocket的所有权就会立即转移回应用程序:

var socket = socketInformation.DatagramSocket;

之后,您应该注册一个MessageReceived处理程序以读取接收到的数据。 DatagramSocket类没有InputStream属性。它遵循基于事件的传入I / O模型。

即使 SocketActivityTrigger 在数据报到达时引发后台任务,它也不会耗尽套接字。数据仍将在那里,等待应用程序注册MessageReceived处理程序。

@ grace-feng-mst的答案中缺少的关键一件事是将套接字转移回代理:

public async void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();
    try
    {
        var details = taskInstance.TriggerDetails as SocketActivityTriggerDetails;
        var socketInformation = details.SocketInformation;
        switch (details.Reason)
        {
            case SocketActivityTriggerReason.SocketActivity:
                var socket = socketInformation.DatagramSocket;
                socket.MessageReceived += Socket_MessageReceived;

                // Wait for data to be read by MessageReceived handler (e.g., waiting on an event that is signaled by the handler).
                // Write some data.

                // Transfer socket ownership back to the broker.
                await socket.CancelIOAsync();
                socket.TransferOwnership(…);
                break;
            default:
                break;
        }
        deferral.Complete();
    }
    catch (Exception exception)
    {
        ShowToast(exception.Message);
        deferral.Complete();
    }
}

private void Socket_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs args)
{
    using (var reader = args.GetDataReader())
    {
        //TODO: read data here.
    }
}

我已经确认上述代码可以正常工作。外部用户也确认了这一点(请参见here)。