Delphirus - прграммирование на delphi
   Все о delphi Delphirus - прграммирование на delphi
blocks.gif
Навигация
 

Главная
Статьи
Базы данных
Графика
Защита
Интернет
Система
Тексты
Мультимедиа
Файлы
Формы и окна
Другое
Советы
Базы данных
Графика
Интернет
Мультимедиа
Система
Тексты
Файлы
Файлы
Исходники
Компоненты
Инфо
Поиск по сайту
Обратная связь
Самое популярное
Аккаунт
Карта сайта

 
 
 

Советы по delphi \ Интернет и сети \ Сокеты \ Почему несколько блоков при передаче по сокету могут объединяться в один

Почему несколько блоков при передаче по сокету могут объединяться в один

Итак, во-первых, надо заметить, что посылаемые через сокет данные могут не только объединяться в один блок, но и разъединяться по нескольким блокам. Дело в том, что сокет - обычный поток, но в отличие, скажем, от файлового (TFileStream), он передает данные медленнее (сами понимаете - сеть, ограниченный трафик, и т.д.). Именно поэтому две команды:

ServerSocket1.Socket.Connections[0].SendText('Hello, ');
ServerSocket1.Socket.Connections[0].SendText('world!');

совершенно идентичны одной команде:

ServerSocket1.Socket.Connections[0].SendText('Hello, world!');

И именно поэтому, если Вы отправите через сокет файл, скажем, в 100 Кб, то тому, кому Вы посылали этот блок, придет несколько блоков с размерами, которые зависят от трафика и загруженности линии. Причем, размеры не обязательно будут одинаковыми. Отсюда следует, что для того, чтобы принять файл или любые другие данные большого размера, Вам следует принимать блоки данных, а затем объединять их в одно целое (и сохранять, например, в файл). Отличным решением данной задачи является тот же файловый поток - TFileStream (либо поток в памяти - TMemoryStream). Принимать частички данных из сокета можно через событие OnRead (OnClientRead), используя универсальный метод ReceiveBuf. Определить размер полученного блока можно методом ReceiveLength. Также можно воспользоваться сокетным потоком (см. статью про TClientSocket). А вот и небольшой примерчик (приблизительный):

  {Прием файла через сокет}
  procedure TForm1.ClientSocket1Read(Sender: TObject;
    Socket: TCustomWinSocket);
   var l: Integer;
       buf: PChar;
       src: TFileStream;
  begin
    {Записываем в l размер полученного блока}
    l := Socket.ReceiveLength;
    {Заказываем память для буфера}
    GetMem(buf,l+1);
    {Записываем в буфер полученный блок}
    Socket.ReceiveBuf(buf,l);
    {Открываем временный файл для записи}
    src := TFileStream.Create('myfile.tmp',fmOpenReadWrite);
    {Ставим позицию в конец файла}
    src.Seek(0,soFromEnd);
    {Записываем буфер в файл}
    src.WriteBuffer(buf,l);
    {Закрываем файл}
    src.Free;
    {Освобождаем память}
    FreeMem(buf);
  end;

Название: Почему несколько блоков при передаче по сокету могут объединяться в один
Дата публикации: 2004-09-08 (2605 Прочтено)

 
 

 

Page generation 0.035 seconds