Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.01.23;
Скачать: CL | DM;

Вниз

Переслать файл при помощи сокетов.   Найти похожие ветки 

 
Андрей_   (2002-11-25 08:14) [0]

Нужно переслать файл по сети при помощи
ServerSocket и принять его при помощи ClientSocket.
Нашел следующий пример :
на сервере :
{Пересылка файла через сокет}
procedure TForm1.Button2Click(Sender: TObject);
var srcfile:TFileStream;
begin
srcfile:=TFileStream.Create("c:\file.tmp",fmOpenRead);
ServerSocket1.Socket.Connections[0].SendStream(srcfile);
srcfile.Free;
end;

На клиенте:
{Прием файла через сокет}
procedure TForm1.ClientOnRead(Sender: TObject; Socket: TCustomWinSocket);
var l:integer;
buf:PChar;
src:TFileStream;
begin
l:=Socket.ReceiveLength;
GetMem (buf,l+1);
Socket.ReceiveBuf (buf,l);
src:=TFileStream.Create("c:\file.tmp",fmOpenReadWrite);
src.Seek(0,soFromEnd);
src.WriteBuffer(buf,l);
src.Free;
FreeMem (buf);
end;

Текстовый файл при этом пересылается, но программы не завершают корректно свою работу на последних строках с Free.
на сервере строчка srcfile.Free; вызывает исключительную ситуацию class EAccessViolation,
на клиенте src.Free выкидывает виндовскую "Программа выполнила недопустимую операцию и будет закрыта".
FreeMem (buf); также вызывает эту ошибку если по телу программы ее передвинуть перед src.Free;

Хотелось бы разобраться в чем тут дело или может есть другой способ переслать файл, но именно с этими компонентами и по возможности с подробными коментариями т.к. иногда трудно понять некоторые фрагменты программ.
Заранее Спасибо!


 
Reindeer Moss Eater   (2002-11-25 09:06) [1]

Note: The Stream passed as a parameter to SendStream becomes “owned” by the windows socket object. The Windows socket object frees the stream when it is finished with it. Do not attempt to free the stream after it has been passed as a parameter.


 
Андрей_   (2002-11-25 10:09) [2]

Я уберал эти строки из программы, виндовская ошибка все равно возникае в конце выполнения программы.


 
Reindeer Moss Eater   (2002-11-25 10:13) [3]

Есть встроенный отладчик и пошаговое выполнение кода. Так ты узнаешь строку которая вызывает ошибку.


 
Digitman ©   (2002-11-25 11:00) [4]

Socket.ReceiveBuf (buf^,l);


 
dim- ©   (2002-11-25 11:28) [5]

Люди, а что я сделал не так?
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
Var s:string;
srcfile:TMemoryStream;
begin
s:=Socket.ReceiveText;
if s="getimage" then begin
srcfile:=TMemoryStream.Create;
image1.Picture.Graphic.SaveToStream(srcfile);
ServerSocket1.Socket.Connections[0].SendStream(srcfile);
//srcfile.Free;
end;
клиент ни чего не получает, хотя если сделать:
ServerSocket1.Socket.Connections[0].SendText("srcfile");
клиент строку получает


 
Digitman ©   (2002-11-25 12:25) [6]

Где анализ результатов методов SendStream(), SendText() ?
Где обработка события OnClientWrite() ?
На основании чего предаолагается, что в результате
s:=Socket.ReceiveText;
приемник ВСЕГДА получит в s строчку ИМЕННО в таком виде "srcfile"


 
dim- ©   (2002-11-25 14:38) [7]

а при ServerSocket1.Socket.Connections[0].SendStream(srcfile);
на клиенте событие OnClientWrite() даже не наступает.
А как проанализировать результат методов SendStream(), SendText()?


 
Digitman ©   (2002-11-25 14:54) [8]


> на клиенте событие OnClientWrite() даже не наступает.


А с какого хрена оно должно там наступить-то ? Это событие возбуждается тем компонентом, send-функция которого был вызвана.
И, кроме того, однократно - следом же за событием On[Client]Connect, извещая тем самым, что для этого компонента с этого момента можно вызывать Send-методы

Если send-функция (вызванная ГДЕ УГОДНО в неблок.режиме) вернула отказ в той или иной форме (см.хэлп на конкр. send-функцию), нужно "чуть-чуть подождать" и попытаться повторить вызов send-функции в обработчике события On[Client]Write, указав, что следует повторно поместить в очередь передачи.

Во всех противных случаях On[Client]Write не возбуждается.


 
dim- ©   (2002-11-25 15:27) [9]

перепутал я
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var l:integer;
buf:PChar;
src:TMemoryStream;
begin
l:=Socket.ReceiveLength;
memo1.Lines.Add(inttostr(l));
GetMem (buf,l+1);
Socket.ReceiveBuf (buf,l);
src:=TMemoryStream.Create;
src.Seek(0,soFromEnd);
src.WriteBuffer(buf,l);
src.Free;
FreeMem (buf);
image1.Picture.Graphic.LoadFromStream(src);
end;
но все равно не работает!!


 
Digitman ©   (2002-11-25 15:36) [10]


> перепутал я


Чего "перепутал"-то ? У тебя передатчик как положено не работает, а ты приемником занялся.
Реализуй сквозную логику передатчика как положено - потом за приемник возьмешься. В неблок.режиме при передаче данных корректная обработка OnWrite() на стороне передатчика О-БЯ-ЗА-ТЕЛЬ-НА !


 
dim- ©   (2002-11-25 15:58) [11]

Будешь смеяться но ServerSocket1ClientWrite стабатывает только в момент конекта, а потом молчит


 
Digitman ©   (2002-11-25 16:16) [12]

значит, ничего не ставишь в очередь на передачу.

либо постановка в очередь на передачу всего потока прошла успешно за один вызов SensStream() и весь поток уже ушел к клиенту


 
dim- ©   (2002-11-25 20:10) [13]

а клиент ничего не получает, передоваемый размер srcfile.size=800323, что еще можно попробывать сделать
Может есть какой рабочий примерчик?


 
SV ©   (2002-11-26 01:07) [14]

А не проще через апи TransmitFile ;)


 
Андрей_   (2002-11-26 06:24) [15]

Уважаемый Digitman !
Все заработало, спасибо большое !
Socket.ReceiveBuf (buf^,l);
src.WriteBuffer(buf^,l);
А что означает этот знак ^ ?



 
Digitman ©   (2002-11-26 08:14) [16]

^ - разыменование переменной указательного типа


 
Digitman ©   (2002-11-26 08:18) [17]

http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1038223369&n=4



Страницы: 1 вся ветка

Текущий архив: 2003.01.23;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.017 c
14-72497
Dr.Sergey
2003-01-01 14:05
2003.01.23
Подскажите пожалуйста


14-72536
БиМ
2003-01-05 07:52
2003.01.23
Virtual & Override


3-72056
relaxer
2003-01-04 17:06
2003.01.23
Хелп! Unsupported feature в IBX ...


4-72598
Novichek
2002-11-05 19:15
2003.01.23
блокирование набора


6-72431
Konsul
2002-11-24 15:22
2003.01.23
Dial-up