UWP c#从StreamSocket读取XML

时间:2017-10-10 16:45:56

标签: c# sockets uwp xmpp

我正在尝试通过TCP网络套接字(StreamSocket)与XMPP(Jabber)服务器通信,我正在使用以下代码来读取服务器发送给我的内容:

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个字符,连接两个字符串并将它们作为一个字符串返回。

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

2 个答案:

答案 0 :(得分:0)

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

您应该能够获得Stream中的实际长度,我们可以使用Stream.Length来获取流的长度(以字节为单位)。 Array的最后一个char是“\ 0”。创建char数组时,您应该能够将Stream.Length加1设置为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方法。

答案 1 :(得分:0)

我终于想出了阅读长信息: 我必须使用DataReaderDataWriter代替StreamReaderStreamWriter

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

private StreamSocket socket;
private DataReader dataReader;
private DataWriter dataWriter;

public string readNextString() {
    string result = "";
    readingCTS = new CancellationTokenSource();

    try {
        uint readCount = 0;

        // Read the first batch:
        Task < uint > t = dataReader.LoadAsync(BUFFER_SIZE).AsTask();
        t.Wait(readingCTS.Token);
        readCount = t.Result;

        if (dataReader == null) {
            return result;
        }

        while (dataReader.UnconsumedBufferLength > 0) {
            result +=dataReader.ReadString(dataReader.UnconsumedBufferLength);
        }

        // If there is still data left to read, continue until a timeout occurs or a close got requested:
        while (!readingCTS.IsCancellationRequested && readCount >= BUFFER_SIZE) {
            t = dataReader.LoadAsync(BUFFER_SIZE).AsTask();
            t.Wait(100, readingCTS.Token);
            readCount = t.Result;
            while (dataReader.UnconsumedBufferLength > 0) {
                result += dataReader.ReadString(dataReader.UnconsumedBufferLength);
            }
        }
    }
    catch(AggregateException) {}
    catch(NullReferenceException) {}

    return result;
}