Alright, so I understand the whole idea that TCP is stream based and not message based - I don't care about that.
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. 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? 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), typ开发者_C百科eof(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. 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?
Alright, so I understand the whole idea that TCP is stream based and not message based - I don't care about that.
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.
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);
}
}
}
精彩评论