2013-12-18 45 views
1

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

但有时似乎从传入数据的前8个字节被跳过,并与步骤1-4我读取包的数据中的前8个字节。

用于接收

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

下面的代码插座无限循环:

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); 
    } 
+0

发送者和接收者应使用相同的内容协议。有没有? – Silvermind

+0

包装结构对于所有方向都是相同的。包中的数据可能是一切。但是包的长度必须正确 –

+0

通常,这样的问题是由于执行recv循环和错误地处理缓冲区索引/指针造成的。代码请致电:) –

回答

0

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

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

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