NetworkStream等效

时间:2012-07-03 07:26:54

标签: c# .net sockets windows-runtime

我一直在尝试创建一个metro应用程序,但是有一个问题:StreamSocket并没有真正做我想做的事情(我认为)

以下是我的.Net代码的摘录:

        try
        {
            TCP = new TcpClient(server, port);
            Stream = TCP.GetStream();
            Read = new StreamReader(Stream);
            Write = new StreamWriter(Stream);
        }
        catch (Exception e)
        {
            Console.WriteLine("Error connecting to " + server + ": " + e);
            return;
        }

        // Identify
        Write.WriteLine("LOGIN " + Username);
        Write.Flush();

        while (Connected)
        {
            try
            {
                if ((line = Read.ReadLine()) != null && Connected)

我无法让StreamSocket工作......它要求你知道进入的字符串的长度,我不知道它会是什么 - 它会有所不同。有什么方法可以做到这一点吗?

这就是我所拥有的,但它不起作用:

        try
        {
            // Connect to the server (in our case the listener we created in previous step).
            await Socket.ConnectAsync(new HostName("example.com"), "1111");
        }
        catch (Exception exception)
        {
            // If this is an unknown status it means that the error is fatal and retry will likely fail.
            if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
            {
                throw;
            }
        }

        // Create a DataWriter if we did not create one yet. Otherwise use one that is already cached.
        Writer = new DataWriter(Socket.OutputStream);
        Listener = new DataReader(Socket.InputStream);

        Debug.WriteLine(Socket.Information.RemoteAddress.CanonicalName); //Check if IP is correct

        SendRaw("LOGIN " + Nickname);

        string line = "";
        Connected = true;
        while (Connected)
        {
            if (Listener.UnconsumedBufferLength != 0)
            {
                line = Listener.ReadString(Listener.UnconsumedBufferLength);
                Debug.WriteLine(line);
            }
        }
    }

    async public void SendRaw(string str)
    {
        Writer.WriteString(str);

        // Write the locally buffered data to the network.
        try
        {
            await Writer.StoreAsync();
        }
        catch (Exception exception)
        {
            // If this is an unknown status it means that the error if fatal and retry will likely fail.
            if (SocketError.GetStatus(exception.HResult) == SocketErrorStatus.Unknown)
            {
                throw;
            }
        }
    }

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

首先要做的事情是:您的原始代码是等待发生的DOS攻击。如果可能的话,我建议更改协议,在每个字符串之前包含一个长度前缀,这样你就能分辨出为它分配内存之前的大小。

第二件事:DataReader类必须先将多个字节读入其内部缓冲区才能解释它们。您通过调用LoadAsync来读入此缓冲区。

但是,如果要读取任意长度的字符串,则必须自己读取缓冲区并扫描换行符,如果找不到换行符,则根据需要调整缓冲区大小(或添加新缓冲区) ,最大尺寸。

<强>更新

InputStreamOptions设为Partial;您可以使用任意大的缓冲区大小(例如1024)调用LoadAsync。获取数据后,请致电ReadString(UnconsumedBufferLength)。每次执行此操作时,您可能会获得一条线,一条线或多条线的一部分。因此,您必须按string建立Split然后\n,并在下一次循环中保留任何部分行。