Не могу найти ошибку в коде(передача данных между сервером и клиентом по TCP)

323
08 сентября 2017, 19:38

Здравствуйте, написал некоторое клиент-серверное приложение в котором: 1) Клиент отправляет запрос(просто отправляю в данном примере "SELECT") 2) Сервер в ответ на это отправляет некоторую xml сериализацию обьекта класса Person(в будущем предпологается, что я буду с EntityFramework-а(бд) вытягивать некоторый спектр обьектов по запросу и передавать их клиенту)(пока это неважно). 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;
    }
}

У меня возникает некоторая проблема при получении данных на клиенте. На сервере я спокойно получаю список сериализованых обьектов(в виде строки в которой xml) и передаю их клиенту. На клиенте получаю все данные, но кроме того между переданными данными клиент получает пустую строку. То есть 1ю xml строку я на клиенте получаю все окей, почему то потом клиент получает ""(пустую строку) и дальше получает нормальный обьект. Грубо говоря результат на клиенте получается в таком виде 1)xml1 2)"" 3)xml2 4)"" 5)xml3 6)"" 7)xml4. То есть я то получаю все 4е xml, но так же получаю пустые строки, уже какой час сижу не могу найти свою ошибку, может кто увидит пустую строку которую я передаю?

Answer 1

Скорее всего таким образом сериализуется перенос строки. Нужно сделать настройки чтото подобно этому:

XmlWriterSettings settings = new XmlWriterSettings();
settings.NewLineHandling = NewLineHandling.None;
READ ALSO
Поиск внутренних скобок в выражении

Поиск внутренних скобок в выражении

входная строка -"(m*(g*(3+5))*m)"Нужно достать выражение в самых глубоких скобках (со скобками)

265
Растет потребление памяти

Растет потребление памяти

Не могу разобраться почему утекает память в приложение (winform,net)

340
Правильное оформление проекта [требует правки]

Правильное оформление проекта [требует правки]

Всем доброго времени сутокНеделю назад начал писать большой проект на С#

261
Изменение данных в потоке

Изменение данных в потоке

Начал изучать MVVM и столкнулся с недопониманиемНапример чтобы записать данные из ViewModel во View , необходимо их заполнить в конструкторе ViewModel()

289