2017-10-10 87 views
0

我试图与XMPP通过TCP网络套接字(StreamSocket)(Jabber的)服务器进行通信,我用下面的代码读什么服务器已经发送到我读XML:UWP C#从StreamSocket

StreamSocket tcpSocket; 
StreamReader reader; 
int BUFFER_SIZE = 4096; 

// Connecting to a remote XMPP server .... 

reader = new StreamReader(tcpSocket.InputStream.AsStreamForRead()); 
string result; 
while (true) 
{ 
    result = ""; 
    while (true) 
    { 
     char[] buffer = new char[BUFFER_SIZE]; 
     await reader.ReadAsync(buffer, 0, BUFFER_SIZE); 
     string data = new string(buffer); 

     // Detecting if all elements in the buffer array got replaced => there is more to read 
     if (data.IndexOf("\0") >= 0 || reader.EndOfStream) 
     { 
      result + data.Substring(0, data.IndexOf("\0")); 
      break; 
     } 
     result += data; 
    } 
    Debug.WriteLine(result); 
} 

我的代码适用于长度为< 4096个字符的字符串,但只要字符串获取的时间超过4096个字符,它就会失败(不会检测到消息结束)。它会等待,直到它收到一个新的字符串< 4096个字符,连接两个字符串并将它们返回为一个字符串。

有没有办法获得一个字符串的实际长度并连续读取它们?

回答

0

我终于想通了读长消息: 我要用户reader.Peek()。 。

/// <summary> 
/// How many characters should get read at once max. 
/// </summary> 
private static readonly int BUFFER_SIZE = 4096; 

private StreamSocket socket; 
private StreamWriter writer; 
private StreamReader reader; 

protected async Task<string> readNextStringAsync() 
{ 
    string result = ""; 
    while (true) 
    { 
     char[] buffer = new char[BUFFER_SIZE + 1]; 

     // Read next BUFFER_SIZE chars: 
     reader.ReadAsync(buffer, 0, BUFFER_SIZE); 

     // Cut the read string and remove everything starting from the first "\0": 
     string data = new string(buffer).Substring(0, buffer.Length - 1); 
     int index = data.IndexOf("\0"); 
     if (index < 0) 
     { 
      index = data.Length; 
     } 
     result += data.Substring(0, index); 

     // Is data left to read? 
     if (reader.Peek() < 0) 
     { 
      // No? then break: 
      break; 
     } 
    } 
    return result; 
} 
0

您已将4096设置为BUFFER_SIZE,并将其设置为StreamReader.ReadAsync和char阵列中的count参数。当字符串包含超过4096个字符时,它将失败。

您应该能够获得流中的实际长度,我们可以使用Stream.Length以字节为单位获取流的长度。 Array的最后一个字符是“\ 0”。当你创建char数组时,你应该能够设置Stream.Length加一个char数组。

例如:

StreamSocket socket; 
StreamSocket tcpSocket; 
StreamReader reader; 

reader = new StreamReader(tcpSocket.InputStream.AsStreamForRead()); 
var BUFFER_SIZE=(int)(tcpSocket.InputStream.AsStreamForRead()).Length; 
string result; 
while (true) 
{ 
    result = ""; 
    while (true) 
    { 
     char[] buffer = new char[BUFFER_SIZE+1]; 
     await reader.ReadAsync(buffer, 0, BUFFER_SIZE); 
     string data = new string(buffer); 
     if (data.IndexOf("\0") >= 0 || reader.EndOfStream) 
     { 
      result = data.Substring(0, data.IndexOf("\0")); 
      break; 
     } 
     result += data; 
    } 
    Debug.WriteLine(result); 
} 

如果你想读取从当前位置到流的末尾所有字符,你可以使用StreamReader.ReadToEndStreamReader.ReadToEndAsync方法。

+0

感谢您的帮助,但如果我使用'BUFFER_SIZE =(INT)(tcpSocket.InputStream.AsStreamForRead())长;',我得到一个System.NotSupportedException:该流不支持长度属性因为它不是可寻求的。 如果我使用'await reader.readToEndAsync()'它不会返回任何东西 - 它只会等待 – COM8

+0

你可以通过'tcpSocket.InputStream.AsStreamForRead()'方法获取流吗? –

+0

是的,它返回一个流对象,但是''''''''''对象不适用于它返回的这种流。 – COM8