Hello, wrote some client-server application in which: 1) The client sends a request (I just send "SELECT" in this example) 2) The server in response to this sends some xml serialization of an object of the Person class (in the future, I will be with EntityFramework -a (bd) pull out a range of objects on request and transfer them to the client (for now it does not matter). Server code:
class Program { private static Socket server = new Socket(AddressFamily.InterNetworkV6,SocketType.Stream,ProtocolType.Tcp); // private static List<Socket> clients; private static List<Person> persons = new List<Person>() { new Person(0,18,"Sergey 1111"), new Person(1,30,"1111 Maksim"), new Person(2,20,"Pasha 1111"), new Person(3,27,"4444 Ivanov") }; static void Main(string[] args) { StartServer(); Console.ReadLine(); } public static void StartServer() { try { IPEndPoint end = new IPEndPoint(IPAddress.Parse("***::***:***:***:***%***"), 8005); server.Bind(end); server.Listen(10); Console.WriteLine("> server {0} has started", end); server.BeginAccept(AcceptCallback,null); } catch (Exception ex) { Console.WriteLine(ex.Message); } } public static void AcceptCallback(IAsyncResult ar) { Socket client = server.EndAccept(ar); Thread thread = new Thread(HandleClient); thread.Start(client); server.BeginAccept(AcceptCallback, null); } public static void HandleClient(object o) { try { Socket client = (Socket)o; byte[] buffer = new byte[256]; MemoryStream ms = new MemoryStream(new byte[256], 0, 256, true, true); BinaryReader reader = new BinaryReader(ms); BinaryWriter writer = new BinaryWriter(ms); while (true) { ms.ClearMemory(); client.Receive(ms.GetBuffer()); string cmd = reader.ReadString(); Console.WriteLine("> {0}", cmd); ms.ClearMemory(); switch (cmd) { case "SELECT": { SendQueryResult(client); break; } }; writer.Write("server> Message sent"); client.Send(ms.GetBuffer()); } }catch(Exception ex) { Console.WriteLine(ex.Message); } } public static void SendQueryResult(object o) { List<string> query_result = new List<string>(); Socket client = (Socket)o; MemoryStream ms = new MemoryStream(new byte[512], 0, 512, true, true); BinaryReader reader = new BinaryReader(ms); BinaryWriter writer = new BinaryWriter(ms); ms.ClearMemory(); foreach(Person p in persons) { query_result.Add(p.Serialize()); } foreach(string xml in query_result) { ms.ClearMemory(); writer.Write(xml); client.Send(ms.GetBuffer()); } } public static bool SocketConnected(Socket s) { bool part1 = s.Poll(1000, SelectMode.SelectRead); bool part2 = (s.Available == 0); if (part1 && part2) return false; else return true; } } public static class EMethods { public static void ClearMemory(this MemoryStream stream) { Array.Clear(stream.GetBuffer(), 0, stream.GetBuffer().Length); stream.Position = 0; } public static string Serialize<T>(this T value) { if (value == null) { return string.Empty; } try { var xmlserializer = new XmlSerializer(typeof(T)); var stringWriter = new StringWriter(); using (var writer = System.Xml.XmlWriter.Create(stringWriter)) { xmlserializer.Serialize(writer, value); return stringWriter.ToString(); } } catch (Exception ex) { throw new Exception("An error occurred", ex); } } } Client code:
class Program { private static string querydata = "EMPTY"; private static List<XmlDocument> xml_results = new List<XmlDocument>(); private static Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); private static MemoryStream ms = new MemoryStream(new byte[256], 0, 256, true, true); private static BinaryWriter writer = new BinaryWriter(ms); private static BinaryReader reader = new BinaryReader(ms); static void Main(string[] args) { IPEndPoint IPend = new IPEndPoint(IPAddress.Parse(""***::***:***:***:***%***""), 8005); socket.Connect(IPend); Console.WriteLine("> successfully connected to {0}", IPend); while (true) { Console.Write("cmd> "); string cmd = Console.ReadLine(); //MemoryStream m_stream = new MemoryStream(buffer); // BinaryWriter b_writer = new BinaryWriter(m_stream); switch (cmd) { case "exit": { return; } case "select": { querydata = "SELECT"; break; } case "create": { querydata = "CREATE"; break; } case "update": { querydata = "UPDATE"; break; } case "delete": { querydata = "DELETE"; break; } }; List<string> query_result = new List<string>(); SendPacket(querydata); while(true) { string result = ReceivePacket(); if(result == "server> Result sent" || result == "server> Message sent") { break; } else { query_result.Add(result); } } foreach(var xml_str in query_result) { XmlDocument document = new XmlDocument(); document.LoadXml(xml_str); xml_results.Add(document); } ViewXMLResult(xml_results); xml_results.Clear(); query_result.Clear(); } } public static void ViewXMLResult(List<XmlDocument> list) { foreach(var doc in list) { XmlElement elem = doc.DocumentElement; XmlNode node = elem.SelectSingleNode("PersonID"); XmlNode node1 = elem.SelectSingleNode("Age"); XmlNode node2 = elem.SelectSingleNode("FullName"); Console.WriteLine("Xml ID = {0} \nXml Age = {1} \nXml FullName = {2}", node.InnerText, node1.InnerText, node2.InnerText); Console.WriteLine(); } } public static void ConnectToServer(Socket sock, IPEndPoint end) { try { sock.Connect(end); Console.WriteLine("> successfully connected to {0}", end); } catch (Exception ex) { Console.WriteLine(ex); } } public static void SendPacket(string data) { ms.ClearMemory(); writer.Write(data); socket.Send(ms.GetBuffer()); } public static string ReceivePacket() { ms.ClearMemory(); socket.Receive(ms.GetBuffer()); string message = reader.ReadString(); Console.WriteLine(message); return message; } } public static class EMethods { public static void ClearMemory(this MemoryStream stream) { Array.Clear(stream.GetBuffer(), 0, stream.GetBuffer().Length); stream.Position = 0; } } I'm having some problem getting data to the client. On the server, I calmly get a list of serialized objects (as a string in which xml) and pass them to the client. On the client, I get all the data, but in addition, between the transferred data, the client receives an empty string. That is, the 1st xml string I get everything on the client is ok, for some reason the client then gets a “” (empty string) and then gets a normal object. Roughly speaking, the result on the client is obtained in this form 1) xml1 2) "" 3) xml2 4) "" 5) xml3 6) "" 7) xml4. That is, I’m getting all 4x xml, but I’m also getting blank lines, what time I’m sitting I can’t find my mistake, can anyone see the empty line that I am passing?