【问题标题】:NetworkStream never writes dataNetworkStream 从不写入数据
【发布时间】:2011-08-27 06:35:53
【问题描述】:

好的,所以我理解 TCP 是基于流而不是基于消息的整个想法 - 我不在乎。

我想要做的是尝试简单地序列化某些内容并通过网络将其发送到另一个使用相同基于消息的协议的应用程序。

问题在于,每当我序列化数据(我正在序列化为 XML),然后将其写入网络流时,该死的东西永远不会写入它 - 永远。直到我关闭程序并关闭流,流才真正发送数据。到底发生了什么 - TCP 是否在等待足够的数据发送?是不是在等我什么? (我怀疑前者,因为我可以写简单的行,而且做得很好。)

这是我的客户的代码:

        TcpClient client = new TcpClient();
        client.Connect(IPAddress.Parse("127.0.0.1"), 10100);
        NetworkStream ns = client.GetStream();
        StreamWriter writer = new StreamWriter(ns);

        ListenerThread th = new ListenerThread(new StreamReader(ns));
        new Thread(th.run).Start();

        XmlSerializer serializer = new XmlSerializer(typeof(Message), new Type[] {typeof(AuthenticationMessage), typeof(ChangeChatRoomMessage), typeof(ChangePasswordMessage), typeof(ConnectionStatusMessage), typeof(InitializeMessage), typeof(StatusMessage), typeof(SuccessMessage), typeof(TextMessage)});

        string file =  "<some test xml file>";
        while(true)
        {
            FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read);
            StreamReader reader = new StreamReader(stream);
            Message newmsg = (Message)serializer.Deserialize(reader);
            stream.Close();

            serializer.Serialize(writer, newmsg);
            writer.Flush();

            file = Console.ReadLine();
        }

这是服务器的代码:

    public void HandleMessage()
    {
        Message msg = (Message)serializer.Deserialize(reader);
        Console.WriteLine("Read Message " + msg.GetType());
    }

    public void Start()
    {
        while(true)
        {
            Socket socket = listener.AcceptSocket();
            NetworkStream stream = new NetworkStream(socket);
            reader = new StreamReader(stream);
            HandleMessage();
            stream.Close();
        }
    }

我的程序现在已经运行了 20 分钟,没有任何东西发送到服务器。我尝试了所有我能想到的方法,刷新了我的写入器缓冲区(显然是 TextWriter,而不是 NetworkStream),并将客户端设置为 NoDelay 等……发生了什么以及为什么?

【问题讨论】:

  • 注意:您的客户端和服务器不一致 - 服务器希望每个连接只发送一条消息,但客户端在单个连接上发送多条消息。
  • 猜测,XmlSerializer.Deserialize 正在等待数据结束,直到客户端关闭连接才会发生。
  • 老兄!谢谢。一开始我怀疑是不是这样,因为我实际上是先将它读入缓冲区以测试这是否是问题所在。问题是,当我将它读入缓冲区时,我做了 ReadToEnd() *-_- 。大声笑这可以解释,直到最后你才真正得到流的结束,反序列化可能像文件一样读取它,等待那个 EOS。我只是逐行阅读它,直到文件的最后一行(无论如何现在应该始终是 - 只是我正在努力解决的一项任务)非常有帮助!谢谢

标签: c# .net networking tcp tcpclient


【解决方案1】:

好的,所以我理解 TCP 是基于流的整个想法,并且 不是基于消息的 - 我不在乎。

其实这很重要,你应该关心它。在向服务器发送数据时,您不仅应该尝试发送一些消息,还应该定义一些协议(或使用现有协议之一),客户端在其中向服务器指示它打算发送多少数据。

下面是一个示例,说明您可以如何进行。在此示例中,客户端将总消息的长度作为前 4 个字节发送。

服务器:

class Program
{
    static void Main()
    {
        var listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, 10100));
        listener.Start();
        while (true)
        {
            using (var client = listener.AcceptTcpClient())
            using (var stream = client.GetStream())
            using (var reader = new BinaryReader(stream))
            {
                // The first 4 bytes of the message will indicate
                // the total message length
                var length = reader.ReadInt32();
                var buffer = reader.ReadBytes(length);
                Console.WriteLine("Received {0} bytes from client:", length);
                Console.WriteLine("{0}", Encoding.UTF8.GetString(buffer));
            }
        }
    }
}

客户:

class Program
{
    static void Main()
    {
        using (var client = new TcpClient("127.0.0.1", 10100))
        using (var stream = client.GetStream())
        using (var writer = new BinaryWriter(stream))
        {
            var message = "<some test xml file>";
            var buffer = Encoding.UTF8.GetBytes(message);
            // Send the total message length in the first 4 bytes
            // so that the server knows how much it has to read
            writer.Write(buffer.Length);
            writer.Write(buffer);
            Console.WriteLine("Successfully sent {0} bytes to server", buffer.Length);
        }
    }
}

【讨论】:

    猜你喜欢
    • 2012-02-17
    • 1970-01-01
    • 2014-08-30
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    相关资源
    最近更新 更多