Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 Передача разных файлов через Socket в неблокирующем режиме  [new]
OxY63rus
Member

Откуда:
Сообщений: 135
Здравствуйте! Знаю, вопрос избит, но всё же прошу помощи.

Компонент TServerSocket/TClientSocket
Сокеты в неблокирующем режиме

Клиент отправляет:
    Buffer: array [0 .. 4095] of byte;
    LenBuf: int64;

      FileStream:=TFileStream.Create(OriginalName, fmOpenRead);
      FileStream.Position:=0;
      while FileStream.Position< FileStream.Size do
      begin
        LenBuf:=FileStream.Read(Buffer,SizeOf(Buffer));
        Client.Socket.SendBuf(Buffer,LenBuf);
        Application.ProcessMessages;
      end;
      FileStream.Free;


Сервер принимает:
      Buffer: Pointer;

      len:= Socket.ReceiveLength;
      GetMem(Buffer, len);
      datalen:=Socket.ReceiveBuf(Buffer^,len);          //datalen- сколько локально пришло
      FileStream.Write(Buffer^,datalen);
      DataSize:=DataSize+datalen;                           //DataSize - сколько уже записано глобально
      FreeMem(Buffer);
      if DataSize=Size then                                       // Size - заранее известное глобальное "сколько всего надо"
      begin
        FileStream.Free;
        Socket.Close;
      end;


В итоге небольшие (~до 3 Мб) файлы принимаются нормально, далее начинаются проблемы.

Я пробовал даже просто прочитать пришедшую длину ReceiveLength и считать буфер в никуда. Это для того чтобы просто просуммировать все ReceiveLength при срабатывании события прихода данных. В итоге сумма всех ReceiveLength меньше чем длина ожидаемого файла.

В какую сторону подумать?
4 апр 19, 00:01    [21851912]     Ответить | Цитировать Сообщить модератору
 Re: Передача разных файлов через Socket в неблокирующем режиме  [new]
Foxpc
Member

Откуда:
Сообщений: 152
юзай SendStream передавая в него TFileStream а принимаешь через ReceiveBuf. Логично же
4 апр 19, 00:20    [21851921]     Ответить | Цитировать Сообщить модератору
 Re: Передача разных файлов через Socket в неблокирующем режиме  [new]
Foxpc
Member

Откуда:
Сообщений: 152
г.ы
http://www.delphisources.ru/pages/faq/base/file_tserversocket_to_tclientsocket.html
4 апр 19, 00:24    [21851923]     Ответить | Цитировать Сообщить модератору
 Re: Передача разных файлов через Socket в неблокирующем режиме  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1435
Ну вот в лоб.. 200 Мб передает без проблем...

procedure TForm3.Button1Click(Sender: TObject);
begin
  ClientSocket1.Socket.SendStream(TFileStream.Create('e:\200mb.zip', fmOpenRead));
end;

procedure TForm3.FormCreate(Sender: TObject);
begin           ReportMemoryLeaksOnShutdown := True;
  ServerSocket1.Open;
  ClientSocket1.Open;
end;

procedure TForm3.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
begin
  var fs := TFile.Open('e:\200mb_NEW.zip', TFileMode.fmOpenOrCreate);
  fs.Seek(0, TSeekOrigin.soEnd);
  var sz := Socket.ReceiveLength;
  var Buf: TBytes;
  SetLength(Buf, sz);
  sz := Socket.ReceiveBuf(Buf[0], sz);
  fs.WriteData(Buf, sz);
  fs.Free;
end;
4 апр 19, 01:00    [21851931]     Ответить | Цитировать Сообщить модератору
 Re: Передача разных файлов через Socket в неблокирующем режиме  [new]
OxY63rus
Member

Откуда:
Сообщений: 135
Спасибо большое всем откликнувшимся.
Приём файла, как оказалось, шёл нормально. Намудрил с буферной передачей. С помощью SendStream всё заработало. Но всё-таки хочу запилить прогрессбар, поэтому буду разбираться.

А пока факультативный вопрос на соображение, кому интересно:
у меня есть свой TObject, содержащий все необходимые для передачи файла проперти. Также в нём же содержится TClientSocket и TFileStream. В конструкторе моего объекта это всё создаётся динамически. Механизм такой. Вызываем
MyObject.OriginalName:='testfile.tmp';
MyObject.Send

По этой команде ClientSocket цепляется к заранее известному хосту и в событии OnConnect отправляет всю необходимую инфу приёмнику. Приёмник отвечает одобрением текстовой строкой. В событии OnRead я ловлю эту строку, перевожу флаг моего объекта в режим Receiving:=True и начинаю отправлять файл. Когда приёмник принял весь файл он закрывает соединение. В событии OnDisconnect я хочу дестроить свой объект, но не получается. По отладчику вижу, что всё содержимое освобождается нормально, но потом управление возвращается в OnDisconnect, а собственно сокет я уже убил и лювлю исключение. Что посоветуете?
4 апр 19, 10:33    [21852189]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить