简体   繁体   English

WP8中的System.Net.Sockets

[英]System.Net.Sockets in WP8

Got unknown issue with System.Net.Sockets in WP8. WP8中的System.Net.Sockets出现未知问题。 The communication built on next schema - 4 first bytes - for package length, next 4 bytes for package number, and data. 通讯建立在下一个模式(包长度的前4个字节),包编号的后4个字节和数据上。 So [4][4][{any}] is a TCP package. 因此[4] [4] [{any}]是一个TCP程序包。 Reading of incoming data goes by next steps. 下一步将读取传入的数据。 1. Read first 8 bytes. 1.读取前8个字节。 2. Get package length from the first 4 bytes to determine size of incoming data. 2.从前4个字节获取包长度,以确定传入数据的大小。 3. Resize buffer to a proper size. 3.将缓冲区大小调整为适当的大小。 4. Read incoming data in buffer with offset 8 bytes. 4.读入偏移为8个字节的缓冲区中的输入数据。 I am sending a lot of packages to server. 我正在向服务器发送很多软件包。 Sometimes server's responses in incoming buffer are valid and can be read one by one. 有时,服务器在传入缓冲区中的响应是有效的,并且可以一一读取。

But sometimes it seems the first 8 bytes from incoming data are skipped and with the steps 1-4 I am reading the first 8 bytes from the package's data. 但是有时候似乎传入数据的前8个字节被跳过了,在1-4步中,我从包的数据中读取了前8个字节。

Infinite loop for receiving 无限循环接收

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

Here code for 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);
    }

It is 100% issue with crossthreading. 交叉线程是100%的问题。 Did the same in Console app. 在控制台应用程序中做了同样的事情。 If here 如果在这里

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

before mre.Wait() put Thread.Sleep(n), where n > 1 - everything works fine. 在mre.Wait()之前放入Thread.Sleep(n),其中n> 1-一切正常。 But this is very rude solution 但这是非常不礼貌的解决方案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM