Не могу понять, как правильно передавать по сети..
От: MasterKlass Россия http://trial.zelek.ru
Дата: 26.10.06 23:55
Оценка:
Есть сервер и клиент.. (работают асинхронно)
Сервер посылает клиенту допустим 10кб информации..
Клиент же полчает сначала 1040, а потом ещё дополучает...

Могу привести кода немножко)

сервер:
        public void SearchFileOnServer(String Path, String FileMask, UserConnection Sender)
        {
            Int32 CountOfFounfFiles = 0, CountOfSendBytes = 0;
            String AllFounfFiles = "";
            Sender.SendData("BEGIN_TO_FIND|");
            SetRichTextBoxText("Start Searching for " + FileMask + " in " + Path + " and Subdirectories...\n");
            ScrollRichTextBox(-1);
            try
            {
                foreach (String FoundFile in Directory.GetFiles(Path, FileMask, System.IO.SearchOption.TopDirectoryOnly))
                {
                    AllFounfFiles += FoundFile + "|"; // накапливаем строку из найденных файлов
                    CountOfFounfFiles++;              // кол-во найденных фалов
                    CountOfSendBytes += AllFounfFiles.Length; // кол-во "найденных" БАЙТОВ (имена файлов)
                    if (AllFounfFiles.Length > 10000) // если длина всех найденных файлов больше 948576 б,
                                                      // то пошлём клиенту часть  и обнулим строку
                    {
                        Sender.SendData("FOUNDFILE|" + AllFounfFiles);
                        AllFounfFiles = "";
                    }
                }
            }
            catch (DirectoryNotFoundException ex)
            {
                SetRichTextBoxText("Directory " + Path + " not found!\n");
                // ПОСЛАТЬ КЛИЕНТУ ОШИБКУ
                return;
            }
            catch (UnauthorizedAccessException ex) // ВОЗНИКАЕТ, ЕСЛИ НЕТ ДОСТУПА К ПАПКЕ
            {
                MessageBox.Show(ex.Message);
                SetRichTextBoxText("Search error!\n");
                // ПОСЛАТЬ КЛИЕНТУ ОШИБКУ Sender.SendData("ERROR|"...);
                return;
            }
            try
            {
                foreach (String dir in SearchFiles.GetAllDirectories(Path))
                    foreach (String FoundFile in Directory.GetFiles(dir, FileMask, System.IO.SearchOption.TopDirectoryOnly))
                    {
                        AllFounfFiles += FoundFile + "|";
                        CountOfFounfFiles++;
                        CountOfSendBytes += AllFounfFiles.Length;
                        if (AllFounfFiles.Length > 10000) // если длина всех найденных файлов больше 80 r,? то пошлём коиенту 
                        {
                            Sender.SendData("FOUNDFILE|" + AllFounfFiles);
                            AllFounfFiles = "";
                        }
                    }
            }
            catch (UnauthorizedAccessException ex) // ВОЗНИКАЕТ, ЕСЛИ НЕТ ДОСТУПА К ПАПКЕ
            {
                //MessageBox.Show(ex.Message);
                SetRichTextBoxText("Search error!\n");
                // ПОСЛАТЬ КЛИЕНТУ ОШИБКУ Sender.SendData("ERROR|"...);
                return;
            }
            catch (Exception ex)
            {
                //MessageBox.Show(ex.Message);
                SetRichTextBoxText("Search error!\n");
                // ПОСЛАТЬ КЛИЕНТУ ОШИБКУ Sender.SendData("ERROR|"...);
                return;
            }
            SetRichTextBoxText("Search complete! Found " + CountOfFounfFiles.ToString() +
                " files. Send to client " + CountOfSendBytes + " bytes.\n");
            Sender.SendData("FOUNDFILE|" + AllFounfFiles);

        }

        public void SendData(String Data)
        {
            // закрываем поток от других. чтобы быть уверенными, что нам никто не помешает =)
            lock (Client.GetStream())
            {
                StreamWriter wrt = new StreamWriter(Client.GetStream());
                wrt.Write(Data + (char)13 + (char)10);
                // чтобы все данные записались
                wrt.Flush();
            }
        }


Клиент:
        private void DoRead(IAsyncResult ar)
        {
            Int32 BytesRead;
            String strMessage;

            try
            {
                // Заканчивает чтение данных в readBuffer и возвращает кол-во прочитанных байт
                // lock (Client.GetStream())
                {
                    BytesRead = Client.GetStream().EndRead(ar);
                }
                if (BytesRead < 1)
                {
                    // TO_DO!!! если ничего не было прочитано то server закрыт. Отметить, что разъединено в catch
                    // MarkAsDisconnected();
                    return;
                }
                // конвертируем в кодировку UTF8 и отнимаем 2 байта: Chr(13) и Chr(10)
                strMessage = Encoding.UTF8.GetString(readBuffer, 0, BytesRead - 2);
                // анализируем команды
                ProcessCommands(strMessage);
                // заново начинаем чтение
                Client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
            }
            catch (IOException ex)
            {
                MessageBox.Show("Сервер разорвал сеодинение. Возможно он завершил работу. Попробуйте подключиться позже.",
                    "LocalNetSearchClient Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                MenuStripChangeDisconnect(Color.Red, "Нет соединения с сервером", true);
            }
            catch (Exception e)
            {
                //MessageBox.Show(e.Message);
                //отсоединитьсяToolStripMenuItem_Click(null, null);
            }
        }


наверняка я неправильно что-то делаю... но что?
Не могу понять, как правильно передавать по сети..
От: Аноним  
Дата: 27.10.06 07:14
Оценка:
Что это READ_BUFFER_SIZE?
И что Вас удивляет?
BytesRead = Client.GetStream().EndRead(ar);
а затем
Client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Не могу понять, как правильно передавать по сети..
От: Аноним  
Дата: 27.10.06 10:54
Оценка:
READ_BUFFER_SIZE — размер массива, куда считываем...

хм...
я брал за основу пример MS из 101 примера для .net..
там так.. саам немного удивился поначалу..
как же тогда написать?


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re: Не могу понять, как правильно передавать по сети..
От: MasterKlass Россия http://trial.zelek.ru
Дата: 28.10.06 12:11
Оценка:
Надо сначала Beginread() где-нить указать?


Здравствуйте, masterklass, Вы писали:

M>READ_BUFFER_SIZE — размер массива, куда считываем...


M>хм...

M>я брал за основу пример MS из 101 примера для .net..
M>там так.. саам немного удивился поначалу..
M>как же тогда написать?

M>
данное сообщение получено с www.gotdotnet.ru

M>ссылка на оригинальное сообщение
Re[2]: Не могу понять, как правильно передавать по сети..
От: MasterKlass Россия http://trial.zelek.ru
Дата: 28.10.06 13:32
Оценка:
Кстати я это и делаю..
Как только к серверу подключаюсь..

            try
            {
                if (toolStripTextBox1.Text == "" || toolStripTextBox2.Text == "")
                {
                    MessageBox.Show("Введите IP и Port сервера!");
                    return;
                }
                Client = new TcpClient(ServerIP, PORT_NUM);

                // запускаем отдельный поток на получение данных от клиента (чтоб не грузить форму)
                Client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Ошибка при подключении к серверу! Возможно он не запушен или Вы неверно ввели IP или порт сервера!",
                    "LocalNetSearchClient Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                //this.Dispose();
            }


Здравствуйте, MasterKlass, Вы писали:

MK>Надо сначала Beginread() где-нить указать?



MK>Здравствуйте, masterklass, Вы писали:


M>>READ_BUFFER_SIZE — размер массива, куда считываем...


M>>хм...

M>>я брал за основу пример MS из 101 примера для .net..
M>>там так.. саам немного удивился поначалу..
M>>как же тогда написать?

M>>
данное сообщение получено с www.gotdotnet.ru

M>>ссылка на оригинальное сообщение
Re[2]: Не могу понять, как правильно передавать по сети..
От: Аноним  
Дата: 30.10.06 18:11
Оценка:
ну так а всё же...

почему клмент принмает не полностью строку, что я ему посылаю?
в чём может быть проблема?


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[3]: Не могу понять, как правильно передавать по сети..
От: Andrbig  
Дата: 31.10.06 06:50
Оценка: +1
Здравствуйте, masterklass, Вы писали:

M>ну так а всё же...


M>почему клмент принмает не полностью строку, что я ему посылаю?

M>в чём может быть проблема?

Это не проблема, это архитектура сети. Данные разбиваются на пакеты и отправляются пакетами и приходят... точно, тоже пакетами!
Re[4]: Не могу понять, как правильно передавать по сети..
От: MasterKlass Россия http://trial.zelek.ru
Дата: 31.10.06 14:24
Оценка: :)
Здравствуйте, Andrbig, Вы писали:

A>Здравствуйте, masterklass, Вы писали:


M>>ну так а всё же...


M>>почему клмент принмает не полностью строку, что я ему посылаю?

M>>в чём может быть проблема?

A>Это не проблема, это архитектура сети. Данные разбиваются на пакеты и отправляются пакетами и приходят... точно, тоже пакетами!


"Глупая" архитектура! =)
Надо свою сделать)

Но вроде пока всё норм...
Re[4]: Не могу понять, как правильно передавать по сети..
От: Аноним  
Дата: 01.11.06 11:13
Оценка:
нет. не нормально.

попробую объяснить проблему.

Теоретически:
клиент шлёт запрос на поиск допусти всех файлов *.txt на сервере.
Сервер начинает поиск. Нашёл первый файл и отправил его клиенту.
Клиент получает и добавляет имя и путь файла в listbox.

Практически:
С Сервером всё нормально. Посылает по одному файлу за раз.
А вот с Клиентом...
Вот код процедуры, которая принимает соообщения:
            try
            {
                // Заканчивает чтение данных в readBuffer и возвращает кол-во прочитанных байт
                lock (Client.GetStream())
                {
                    BytesRead = Client.GetStream().EndRead(ar);
                }
                if (BytesRead < 1)
                {
                    // TO_DO!!! если ничего не было прочитано то server закрыт. Отметить, что разъединено в catch
                    // MarkAsDisconnected();
                    return;
                }
                // конвертируем в кодировку UTF8 и отнимаем 2 байта: Chr(13) и Chr(10)
                strMessage = Encoding.UTF8.GetString(readBuffer, 0, BytesRead - 2);
                                //fl.WriteLine(strMessage);
                // анализируем команды
                ProcessCommands(strMessage);
                // заново начинаем чтение
                Client.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(DoRead), null);
            }


Первый раз всё нормально, в strMessage содержиться ровно одно имя и путь файла (структура такова — "FOUNDFILE|путь и имя файл|"). А вот потом в strMessage начинают накапливаться имена и пути файлов, т.е. типа такого "FOUNDFILE|файл1|FOUNDFILE|файл2|FOUNDFILE|файл3|FOUNDFILE|файл4|FOUNDFILE|файл5|FOUNDFILE|файл6|FOUNDFILE|файл7|"
и всё бы ничего, но это последовательность в строке может прерваться в самый неподходящий момент, например на середине файла или команды...
Так вот как избежать такого?
Как мне быть уверенным, что приметься только "FOUNDFILE|путь и имя файл|" и всё.
Как сделать, чтобы не накапливалась строка?
Делать огромный буфер на приём (да и то не факт...)?


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.