C# 通过TCP发送长XML

C# 通过TCP发送长XML,c#,xml,serialization,tcp,C#,Xml,Serialization,Tcp,我使用服务器端的TcpListener通过TCP发送对象(类名House),以响应从TcpClient接收到的任何消息 收到消息时,它当前正在填充名为textBox1的文本框 如果我发送一行文本,它工作正常。您会注意到,我有一个多余的行“你好,我是一个服务器”来测试这个目的。但当我发送XML时,它过早地将其切断 当我将序列化的XML发送到流中时,我还从服务器端收到以下错误: 无法从传输连接读取数据:现有 远程主机已强制关闭连接 这是我的服务器代码 // Set the variables for

我使用服务器端的
TcpListener
通过TCP发送对象(类名
House
),以响应从
TcpClient
接收到的任何消息

收到消息时,它当前正在填充名为
textBox1
的文本框

如果我发送一行文本,它工作正常。您会注意到,我有一个多余的行“你好,我是一个服务器”来测试这个目的。但当我发送XML时,它过早地将其切断

当我将序列化的XML发送到流中时,我还从服务器端收到以下错误:

无法从传输连接读取数据:现有 远程主机已强制关闭连接

这是我的服务器代码

// Set the variables for the TCP listener
Int32 port = 14000;
IPAddress ipaddress = IPAddress.Parse("132.147.160.198");
TcpListener houseServer = null;

// Create IPEndpoint for connection
IPEndPoint ipend = new IPEndPoint(ipaddress, port);

// Set the server parameters
houseServer = new TcpListener(port);

// Start listening for clients connecting
houseServer.Start();

// Buffer for reading the data received from the client
Byte[] bytes = new Byte[256];
String data = "hello, this is a house";

// Show that the TCP Listener has been initialised
Console.WriteLine("We have a TCP Listener, waiting for a connection...");

// Continuing loop looking for 
while (true)
{

    // Create a house to send
    House houseToSendToClient = new House
    {
        house_id = 1,
        house_number = 13,
        street = "Barton Grange",
        house_town = "Lancaster",
        postcode = "LA1 2BP"
    };

    // Get the object serialised
    var xmlSerializer = new XmlSerializer(typeof(House));

    using (var memoryStream = new MemoryStream())
    {
        xmlSerializer.Serialize(memoryStream, houseToSendToClient);
    }

    // Accept an incoming request from the client
    TcpClient client = houseServer.AcceptTcpClient();

    // Show that there is a client connected
    //Console.WriteLine("Client connected!");

    // Get the message that was sent by the server
    NetworkStream stream = client.GetStream();

    // Blank int
    int i;

    // Loop for receiving the connection from the client

    // >>> ERROR IS ON THIS LINE <<<
    while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
    {
        Console.WriteLine("here");

        // Take bytes and convert to ASCII string
        data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);

                Console.WriteLine("Received s, return house");

                // Convert the string to a byte array, ready for sending
                Byte[] dataToSend = System.Text.Encoding.ASCII.GetBytes("Hello, I'm a server");

                // Send the data back to the client
                //stream.Write(dataToSend, 0, dataToSend.Length);

                // Send serialised XML in to the stream
                xmlSerializer.Serialize(stream, houseToSendToClient);

    }

    // Close the connection
    client.Close();
}
// Get the object serialised
var xmlSerializer = new XmlSerializer(typeof(House));

// Set the variables for the TCP client
Int32 port = 14000;
IPAddress ipaddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipend = new IPEndPoint(ipaddress, port);

string message = "s";

try
{

    // Create TCPCLient
    //TcpClient client = new TcpClient("localhost", port);
    TcpClient client = new TcpClient();

    // Convert the string to a byte array, ready for sending
    Byte[] dataToSend = System.Text.Encoding.ASCII.GetBytes(message);

    // Connect using TcpClient
    client.Connect(ipaddress, port);

    // Client stream for reading and writing to server
    NetworkStream stream = client.GetStream();

            // Send the data to the TCP Server
            stream.Write(dataToSend, 0, dataToSend.Length);
            //xmlSerializer.Serialize(stream, houseToSend);                        

            // Buffer to store response
            Byte[] responseBytes = new Byte[256];

            string responseData = String.Empty;

            // Read the response back from the server
            Int32 bytes = stream.Read(responseBytes, 0, responseBytes.Length);
            responseData = System.Text.Encoding.ASCII.GetString(responseBytes, 0, bytes);
            textBox1.Text = responseData;


        // Close the stream and the client connection
        stream.Close();
        client.Close();

}
catch (SocketException e)
{
    MessageBox.Show(e.ToString());
}
catch (Exception e)
{
    MessageBox.Show(e.ToString());
}
我已经在代码上标记了出现错误的地方


是因为消息太长吗?

您的客户机代码假设整个消息将在对
Read(…)
方法的一次调用中通过,这是绝对错误的。来自:“即使尚未到达流的结尾,实现也可以自由返回比请求的字节更少的字节。”

对于1024字节的XML文档,您可能需要调用
Read(…)
1024次才能获取整个消息


实际上,最好在发送XML之前发送一个四字节的长度,这样客户机就知道需要多少数据。客户端将读取四个字节,将其转换为整数长度,然后读取更多的字节,然后将这些字节转换为XML。

我刚刚将缓冲区增加到2048,这似乎起到了作用。。。如果有人能解释为什么这样做,请让我知道:)