я пытаюсь отправить изображение от '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 метода? помогите! что я делаю неправильно?
Несмотря на свое название, SendStream () НЕ гарантирует отправку всего потока (особенно, если вы используете неблокирующий сокет). Его возвращаемое значение возвращает фактическое количество отправленных байтов. Если за один вызов отправляется менее полного размера потока, вам придется снова вызвать SendStream (), возможно, много раз, чтобы завершить отправку всего потока (те же проблемы существуют и с SendText ()).
С другой стороны, ReceiveLength () сообщает только о том, сколько байтов доступно в сокете В ЭТОТ МОМЕНТ. Это, вероятно, будет меньше, чем полный отправляемый поток (аналогично, ReceiveText () может не получить полную отправленную строку либо потому, что он использует ReceiveLength () внутри).
Лучший способ отправить поток (или любые произвольные данные в целом) - это сначала отправить размер данных, а затем отправить фактические данные. Продолжайте вызывать SendBuf / Stream / Text () до тех пор, пока этот размер не будет достигнут (если -1 возвращается неблокирующим сокетом без создания исключения, вам нужно дождаться срабатывания события OnWrite сокета, прежде чем сокет снова сможет принять больше данных ). На принимающей стороне сначала прочтите размер, а затем продолжайте чтение, пока не будет достигнут указанный размер. Возможно, вам придется прочитать несколько запусков события OnRead, прежде чем вы получите все данные.
Перейдите на http://www.deja.com и http://forums.embarcadero.com для поиска в архивах групп новостей / форумов Borland / CodeGear / Embarcadero. Я уже много раз публиковал пример кода.
Я не знаю, в чем дело, но я бы попробовал решить более простую проблему. То есть, можете ли вы хотя бы передать что-то простое? Посмотрите, можете ли вы передать c:\hello.txt, содержащий только "Hello", и чтобы он прибыл в правильном порядке. Должно быть легче исследовать поток и результирующий файл, чтобы увидеть, если/где что-то искажается. Если вы не получаете "Hello" на сервере, то знайте, что это не связано с размером или сложностью данных.