WP8中的System.Net.Sockets

时间:2013-12-18 17:00:42

标签: c# sockets windows-phone-8

WP8中的System.Net.Sockets存在未知问题。 通信基于下一个模式 - 4个第一个字节 - 用于包长度,接下来的4个字节用于包号和数据。所以[4] [4] [{any}]是一个TCP包。 读取传入数据的步骤如下。 1.读取前8个字节。 2.从前4个字节获取包长度以确定传入数据的大小。 3.将缓冲区大小调整为适当大小。 4.读取缓冲区中的输入数据,偏移量为8个字节。 我正在向服务器发送大量软件包。 有时服务器在传入缓冲区中的响应是有效的,可以逐个读取。

但有时似乎跳过了输入数据的前8个字节,并且步骤1-4我正在从包的数据中读取前8个字节。

接收无限循环

while (_channel.Opened)
{
    Debug.WriteLine("Wait for incoming... ");
    Stream responseStream = await _channel.Receive();
    HandleIncomingData(responseStream);
}

这里是socket的代码:

    public async Task<Stream> Receive()
    {
        byte[] buff = new byte[8];
        ManualResetEventSlim mre = new ManualResetEventSlim();

        var args = new SocketAsyncEventArgs();

        args.SetBuffer(buff, 0, buff.Length);

        EventHandler<SocketAsyncEventArgs> completed = (sender, eventArgs) => mre.Set();

        EventHandler<SocketAsyncEventArgs> removeSubscription = (sender, eventArgs) => args.Completed -= completed;

        args.Completed += completed;
        args.Completed += removeSubscription;

        _connectionSocket.ReceiveAsync(args);
        mre.Wait();

        args.Completed -= removeSubscription;

        int len = BitConverter.ToInt32(buff, 0);
        int num = BitConverter.ToInt32(buff, 4);

        if (Math.Abs(_packageNumber - num) < 3)
        {
            Array.Resize(ref buff, len);
            args.SetBuffer(buff, 8, buff.Length - 8);

            args.Completed += completed;
            args.Completed += removeSubscription;
            mre.Reset();
            _connectionSocket.ReceiveAsync(args);
            mre.Wait();
        }
        Debug.WriteLine("Recv TCP package: {0}", args.Buffer.ToDebugString());
        if (args.BytesTransferred == 0)
            throw new SocketException();

        byte[] result = new byte[buff.Length - 8];
        Array.ConstrainedCopy(buff, 8, result, 0, result.Length);
        MemoryStream stream = new MemoryStream(result, false);
        return await Task.FromResult(stream);
    }

1 个答案:

答案 0 :(得分:0)

交叉线程是100%的问题。在控制台应用程序中也一样。 如果在这里

mre.Reset();
_connectionSocket.ReceiveAsync(args);
mre.Wait();

在mre.Wait()之前放入Thread.Sleep(n),其中n> 1 - 一切正常。 但这是非常粗鲁的解决方案