从Windows Phone中的tcp套接字读取所有字节的最佳做法是什么?

时间:2013-12-02 11:38:53

标签: c# sockets windows-phone

Windows Phone SDK没有NetworkStream,所有与服务器通信的操作都应该是异步的。

因此,在正常的.net应用程序中,我可以使用类似的东西^

var stream = socket.GetStream();
while ((read = stream.Read (buffer, offset, size)) != 0) 
{
// bufferize it
}

//stream ended and we can parse all bytes.

在Windows Phone中,我只能这样使用:

var args = new SocketAsyncEventArgs();
            args.SetBuffer(buffer, 0, bufferSize);
args.Completed += (sender, eventArgs) =>
            {
// more code here, checking LastOperation, Errors, etc.
...
///
                var gotBuffer = eventArgs.Buffer; // our responce bytes

            };

那么,我如何确定来自服务器的消息是否包含多个bufferSize字节数并读取所有这些消息?

1 个答案:

答案 0 :(得分:0)

好的,我找到了一些解决方法:

在github中,我发现项目“SuperSocket”与Windows Phone支持和实现NetworkStream(https://github.com/kerryjiang/SuperSocket.ClientEngine/blob/master/Core/NetworkStream.cs

但是出于我们的目的,需要对其进行一些更改,因为此代码包含使用ManualResetEvent的阻塞线程读取:

    public override int Read(byte[] buffer, int offset, int count)
    {
       var resetEvent = new ManualResetEvent(false);
       var result = BeginRead(buffer, offset, count, OnComplete, resetEvent);

       resetEvent.WaitOne();
       return EndRead(result);
    }

这将是一个问题,因为只有当socket读取一些数据时才会调用resetEvent.Set(),但是如果服务器没有可用的数据但是仍然建立了连接 - 则套接字不会通知。

因此我们需要为读取操作设置“超时”。这可能是不好的选择,因为所有消息都会因此超时而延迟:

public override int Read(byte[] buffer, int offset, int count)
        {
            var resetEvent = new ManualResetEvent(false);
            var result = BeginRead(buffer, offset, count, OnComplete, resetEvent);

            var res = resetEvent.WaitOne(_readTimeout); // for example 100 ms
            if (res)
                return EndRead(result);
            else
            {
                m_ReceiveEventArgs.Dispose();
                m_ReceiveEventArgs = null;
                return EndRead(new StreamAsyncResult(new SocketAsyncEventArgs(), OnComplete));
            }
        }

如果有人知道更好的方式 - 随意发布回答!