UWP c# read XML from StreamSocket

I'm trying to communicate with an XMPP (Jabber) server via a TCP network socket ( StreamSocket ) and I'm using the following code to read what the server has send to me:

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 || reader.EndOfStream)
        {
            result + data.Substring(0, data.IndexOf(""));
            break;
        }
        result += data;
    }   
    Debug.WriteLine(result);
}

My Code works just fine for strings with a length < 4096 chars, but as soon as the string gets longer than 4096 chars it fails (won't detect the message end). It waits until it receives a new string < 4096 chars, concatenates both strings and returns them as one string.

Is there a way to get the actual length of a string and read them successively?


You have set 4096 to the BUFFER_SIZE and it is be set to the count parameter in StreamReader.ReadAsync and the char Array. When the string contain more than 4096 chars, it will fails.

You should be able to get the actual length in the Stream, we can use Stream.Length to get the length of the stream in bytes. The last char of Array is "". When you create the char Array, you should be able to set the Stream.Length plus one to the char Array.

For example:

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 || reader.EndOfStream)
        {
            result = data.Substring(0, data.IndexOf(""));
            break;
        }
        result += data;
    }
    Debug.WriteLine(result);
}

If you want to reads all characters from the current position to the end of the stream, you can use StreamReader.ReadToEnd or StreamReader.ReadToEndAsync method.


我终于想出了读长信息:我不得不使用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;
}
链接地址: http://www.djcxy.com/p/48296.html

上一篇: 如何在XCode中减少编译时间/加快编译时间?

下一篇: UWP c#从StreamSocket中读取XML