首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >System.Net.Sockets in WP8

System.Net.Sockets in WP8
EN

Stack Overflow用户
提问于 2013-12-18 17:00:42
回答 1查看 271关注 0票数 1

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

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

无限回路接收

代码语言:javascript
复制
while (_channel.Opened)
{
    Debug.WriteLine("Wait for incoming... ");
    Stream responseStream = await _channel.Receive();
    HandleIncomingData(responseStream);
}

下面是套接字的代码:

代码语言:javascript
复制
    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);
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-12-19 15:24:29

这是百分之百的问题与交叉线程。在控制台应用程序中也是如此。如果在这里

代码语言:javascript
复制
mre.Reset();
_connectionSocket.ReceiveAsync(args);
mre.Wait();

在mre.Wait()之前放置Thread.Sleep(n),其中n>1-所有操作都很好。但这是非常粗鲁的解决办法

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20664081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档