проблемы, отправляющие изображение от клиента к серверу

я пытаюсь отправить изображение от 'C:\picture.bmp' до 'c:\temp\picture.bmp' с помощью сервера, и клиентские сокетные клиенты onconnect обработчик событий следующие:

procedure TForm2.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
 var
  fs : tfilestream;
  begin
     fs := TFileStream.create('C:\picture.bmp', fmOpenRead);//picture allready exists
     socket.SendStream(fs);
     fs.free;             
end;

и серверы onclientread как:

procedure TForm2.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  fmm : tfilestream;
  iLen: Integer;
    Bfr: Pointer;
  begin

     iLen := Socket.ReceiveLength;
  GetMem(Bfr, iLen);
  fmm := TFileStream.Create('c:\temp\picture.bmp', fmCreate or 

fmShareDenyWrite);
  try
    Socket.ReceiveBuf(Bfr^, iLen);
    fmm.Write(Bfr^, iLen);
  finally
    FreeMem(Bfr);
    fmm.Free;
  end;

end;

изображение является recieved/created, но любой коррумпирован на, никогда не получался т.е. создавался из-за tfilestream.create метода? помогите! что я делаю неправильно?

1
задан Omair Iqbal 17 July 2010 в 16:36
поделиться

2 ответа

Несмотря на свое название, SendStream () НЕ гарантирует отправку всего потока (особенно, если вы используете неблокирующий сокет). Его возвращаемое значение возвращает фактическое количество отправленных байтов. Если за один вызов отправляется менее полного размера потока, вам придется снова вызвать SendStream (), возможно, много раз, чтобы завершить отправку всего потока (те же проблемы существуют и с SendText ()).

С другой стороны, ReceiveLength () сообщает только о том, сколько байтов доступно в сокете В ЭТОТ МОМЕНТ. Это, вероятно, будет меньше, чем полный отправляемый поток (аналогично, ReceiveText () может не получить полную отправленную строку либо потому, что он использует ReceiveLength () внутри).

Лучший способ отправить поток (или любые произвольные данные в целом) - это сначала отправить размер данных, а затем отправить фактические данные. Продолжайте вызывать SendBuf / Stream / Text () до тех пор, пока этот размер не будет достигнут (если -1 возвращается неблокирующим сокетом без создания исключения, вам нужно дождаться срабатывания события OnWrite сокета, прежде чем сокет снова сможет принять больше данных ). На принимающей стороне сначала прочтите размер, а затем продолжайте чтение, пока не будет достигнут указанный размер. Возможно, вам придется прочитать несколько запусков события OnRead, прежде чем вы получите все данные.

Перейдите на http://www.deja.com и http://forums.embarcadero.com для поиска в архивах групп новостей / форумов Borland / CodeGear / Embarcadero. Я уже много раз публиковал пример кода.

1
ответ дан 2 September 2019 в 22:59
поделиться

Я не знаю, в чем дело, но я бы попробовал решить более простую проблему. То есть, можете ли вы хотя бы передать что-то простое? Посмотрите, можете ли вы передать c:\hello.txt, содержащий только "Hello", и чтобы он прибыл в правильном порядке. Должно быть легче исследовать поток и результирующий файл, чтобы увидеть, если/где что-то искажается. Если вы не получаете "Hello" на сервере, то знайте, что это не связано с размером или сложностью данных.

1
ответ дан 2 September 2019 в 22:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: