2011-10-25 159 views
1

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

收到消息时,它当前正在填充名为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()); 
} 

我上标明错误所在出现的代码。

是否因为讯息太长?

+0

我刚刚增加了2048年的缓冲区,这似乎工作...如果有人可以解释为什么这个作品请让我知道:) – Luke

回答

2

您的客户端代码假设整个消息将通过一次调用Read(...)方法来完成,这是绝对错误的。从MSDN docs“即使未达到流的末尾,实现也可以自由返回比请求更少的字节。”

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

真的,在发送XML之前,您最好发送一个四字节的长度,以便客户端知道需要多少数据。客户端将读取四个字节,将其转换为整数长度,然后读取多个字节,然后将这些字节转换为XML。