简体   繁体   English

NetworkStream永远不会写入数据

[英]NetworkStream never writes data

Alright, so I understand the whole idea that TCP is stream based and not message based - I don't care about that. 好吧,所以我了解TCP是基于流而不是基于消息的整个想法-我不在乎。

What I am trying to do is I am trying to simply serialize something and send it over the network to another application that speaks the same message-based protocol. 我正在尝试做的只是简单地序列化某些内容,然后通过网络将其发送到使用相同基于消息的协议的另一个应用程序。

The problem is that whenever I serialize the data (I'm serializing to XML), and then write it to the network stream, the darn thing never ever writes it - ever. 问题是,每当我序列化数据(将序列化为XML)然后将其写入网络流时,该死的东西永远也不会写入。 It is not until I close the program and the stream is closed that the stream actually sends the data. 直到我关闭程序并关闭流,流才实际发送数据。 What the heck is happening - Is TCP waiting for enough data to send? 到底发生了什么-TCP是否在等待足够的数据发送? Is it waiting for something from me? 它在等待我的东西吗? (I doubt the former because I can do simple write lines and it does those just fine.) (我对前者表示怀疑,因为我可以做简单的写行,而且行得很好。)

Here is the code for my client: 这是我的客户的代码:

        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();
        }

Here is the code for the server: 这是服务器的代码:

    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();
        }
    }

My program has been running for 20 minutes now, and nothing has been sent to the server. 我的程序已经运行了20分钟,并且什么都没有发送到服务器。 I tried everything I could think of, flush my writer buffer (The TextWriter, not the NetworkStream obviously), and set the client to NoDelay, etc... What is happening and why? 我尝试了所有我能想到的一切,刷新了我的编写器缓冲区(TextWriter,显然不是NetworkStream),并将客户端设置为NoDelay,等等...发生了什么,为什么?

Alright, so I understand the whole idea that TCP is stream based and not message based - I don't care about that. 好吧,所以我了解TCP是基于流而不是基于消息的整个想法-我不在乎。

Actually that's very important and you should care about it. 实际上,这非常重要,您应该对此予以关注。 When sending data to the server you should not only try to send some message, you should also define some protocol (or use one of the existing) in which the client indicates to the sever for example how much data it intends to send. 在向服务器发送数据时,您不仅应尝试发送一些消息,还应定义一些协议(或使用现有协议中的一种),客户端在该协议中向服务器指示例如打算发送多少数据。

So here's an example of how you could proceed. 因此,这是您如何进行的示例。 In this example the client sends as the first 4 bytes the length of the total message. 在此示例中,客户端发送总消息的长度作为前4个字节。

Server: 服务器:

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));
            }
        }
    }
}

Client: 客户:

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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM