Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Клиент Серверное приложение  (Прочитано 4867 раз)
0 Пользователей и 1 Гость смотрят эту тему.
tipabot
Интересующийся

by
Offline Offline

« : 25-12-2010 14:27 » 

Есть у меня клиент серверное приложение.
Есть клиент который посылает  сообщения в цикле с помощью метода Write (кстати клиент подключен синхронно к серверу с помощью метода tcpClient.Connect (ipEndPoint)Ага.  Есть сервер вот реализация

Код:
//ЭТО КОНСТРУКТОР
public Server(int port)
          {
            this.tcpListener = new TcpListener(IPAddress.Any, port);
            this.listenThread = new Thread(new ThreadStart(ListenForClients));
            this.listenThread.Start();
           }

private void ListenForClients()

        {
            this.tcpListener.Start();

            while (true)
            {
                //blocks until a client has connected to the server
                TcpClient client = this.tcpListener.AcceptTcpClient();
                //create a thread to handle communication with connected client
                Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
                clientThread.Start(client);
            }
        }

        

        private void HandleClientComm(object client)
        {
            TcpClient tcpClient = (TcpClient)client;

            //Обеспечивает основной поток данных для доступа к сети.
            //Чтобы отправлять и получать данные, используйте метод GetStream для получения объекта NetworkStream
            NetworkStream clientStream = tcpClient.GetStream();

            byte[] message = new byte[999999];
            int bytesRead;

            while (true)
            {
                bytesRead = 0;

                try
                {
                    //blocks until a client sends a message
                    bytesRead = clientStream.Read(message, 0, message.Length);
                }
                catch
                {
                    //a socket error has occured
                    break;
                }

                if (bytesRead == 0)
                {
                    //the client has disconnected from the server
                    break;
                }

                Console.WriteLine("bytesRead=" + bytesRead);

                ASCIIEncoding encoder = new ASCIIEncoding();
                String codingStr = encoder.GetString(message, 0, bytesRead);


                  //ЗДЕСЬ ИДЕТ ОБРАБОТКА ДАННЫХ
                 //ЗДЕСЬ ИДЕТ ОБРАБОТКА ДАННЫХ
                //ЗДЕСЬ ИДЕТ ОБРАБОТКА ДАННЫХ
               //ЗДЕСЬ ИДЕТ ОБРАБОТКА ДАННЫХ
            }
                


            tcpClient.Close();
        }



Проблема в том что сервер не успевает обрабатывать приходящие данные и происходит искажение данных. В результате ексепшены. Ну например выход за пределы массива и т.д. Как сделать так чтоб перед тем как послать новую порцую инфы от клиента, сервер успевал обрабатывать поступившую до этого информацию. Может ответ и очевиден но у меня каша в башке по этой теме  Что, съел?
« Последнее редактирование: 25-12-2010 16:55 от tipabot » Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 25-12-2010 21:27 » 

Проблема в том что сервер не успевает обрабатывать приходящие данные и происходит искажение данных. В результате ексепшены. Ну например выход за пределы массива и т.д. Как сделать так чтоб перед тем как послать новую порцую инфы от клиента, сервер успевал обрабатывать поступившую до этого информацию. Может ответ и очевиден но у меня каша в башке по этой теме  Что, съел?

Вероятно сервер тут не при чем, а проблема в обработчике данных. Например, несинхронизированный доступ потоков к общим данным.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #2 : 26-12-2010 00:57 » 

ну пусть сервер после обработки очередной порции данных сообщит клиенту, что он готов к следующей порции. Это бессорно поможет отцу русской демократии, если конечно проблема была в том, что обработчик сервера не успевает обрабатывать данные.
Записан

С уважением Lapulya
Dale
Блюзмен
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 26-12-2010 01:23 » 

Проблема в том что сервер не успевает обрабатывать приходящие данные и происходит искажение данных. В результате ексепшены. Ну например выход за пределы массива и т.д.

Каким образом определили, что причина именно в этом? Протокол TCP умеет управлять потоком данных, поэтому никаких искажений данных из-за переполнения буфера на приемной стороне не должно быть.
Записан

Всего лишь неделя кодирования с последующей неделей отладки могут сэкономить целый час, потраченный на планирование программы. - Дж. Коплин.

Ходить по воде и разрабатывать программное обеспечение по спецификациям очень просто, когда и то, и другое заморожено. - Edward V. Berard

Любые проблемы в информатике решаются добавлением еще одного уровня косвенности – кроме, разумеется, проблемы переизбытка уровней косвенности. — Дэвид Уилер.
tipabot
Интересующийся

by
Offline Offline

« Ответ #4 : 26-12-2010 10:49 » 

lapulya хотелось бы обойтись малой кровью
Dale
Цитата
Каким образом определили, что причина именно в этом? Протокол TCP умеет управлять потоком данных, поэтому никаких искажений данных из-за переполнения буфера на приемной стороне не должно быть.
По идее вы правы. Но как объяснить следующее. Я поэкспериментировал на простом пример допустим я посылаю серверу информацию в ЦИКЛЕ от ОДНОГО клиента
Код:
int n = 0;
 while (n<5)
{
            clientStream.Write(Encoding.ASCII.GetBytes("1"));
            clientStream.Flush();
            clientStream.Write(Encoding.ASCII.GetBytes("2"));
            clientStream.Flush();
            clientStream.Write(Encoding.ASCII.GetBytes("3"));
            clientStream.Flush();
            clientStream.Write(Encoding.ASCII.GetBytes("4"));
            clientStream.Flush();
            n++;
}

В результате на сервер приходит
то
1 потом 234

то
1234 сразу
ну и т.д. По идее данные должны приходить отдельно т.е. сначала 1 потом 2 и т.д.

Со своими данными я не могу проверить так как у меня передаются куски файла, но похоже ситуация такая же.
Хотя есть еще непонятки с тем что например у меня  файл размером  406 байт. Я его передаю серваку.
Передача данных идет в цикле
1.передаю сначало 210 байт сервер принимает 210 байт; (Пишу и читаю с помощью методов Read и Write)
2.далее передаю остаток 196 бай, а на сервет приходит 199 откуда берутся эти 3 байта вообще не пойму  Меня одолевают смутные сомнения
Ошибок в коде не может быть т.к. я перед передачей и на приеме поставил вывод в лог размер байтовых массивов, короче бред. А черт его знает...
Хотя ошибка может быть вызвана тем что я писал выше в этом посте.
« Последнее редактирование: 26-12-2010 10:54 от tipabot » Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 26-12-2010 11:41 » 

Цитата: tipabot
В результате на сервер приходит
то
1 потом 234

то
1234 сразу
ну и т.д. По идее данные должны приходить отдельно т.е. сначала 1 потом 2 и т.д.
По какой идее? Flush принудительно выталкивает буфер потока на прикладном уровне. Но Flush не означает "послать пакет" на сетевом уровне. И даже если сервер пакеты посылает, хотя не обязан, клиент не обязан на прикладном уровне запускать обработку каждого байта - он накапливает свой буфер.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
tipabot
Интересующийся

by
Offline Offline

« Ответ #6 : 26-12-2010 12:09 » 

Dimka
Все пасиб разобрался, короче буду делать обработку данных когда они полностью передадутся на сервер, а не по частям, как я хотел. Я думал что если я посылаю определенное количество байт, то сервер должен это количество сразу принять (у меня в обработке на сервере массив должен быть всегда кратным 7 по этому если не кратный при итерации по нему вылетал ексепшен выхода за пределы массива)
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 26-12-2010 16:12 » 

tipabot, можно передавать и по частям. Для этого тебе нужно придумать свой протокол прикладного уровня, в котором ты внутрь потока помещаешь разделительные метки частей. И в стек протоколов добавить свой протокол - т.е. поверх библиотечных Stream написать собственный, который умеет записывать и читать данные не байтовыми массивами, а твоими объектами/структурами.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines