![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Переслать файл при помощи сокетов. [D6, Win95/98]
Андрей_ © (2002-11-25 08:14:00)Нужно переслать файл по сети при помощи
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;
Хотелось бы разобраться в чем тут дело или может есть другой способ переслать файл, но именно с этими компонентами и по возможности с подробными коментариями т.к. иногда трудно понять некоторые фрагменты программ.
Заранее Спасибо!
Digitman (2002-11-26 08:18:00) [1]http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1038223369&n=4
Digitman (2002-11-26 08:14:00) [2]^ - разыменование переменной указательного типа
Андрей_ (2002-11-26 06:24:00) [3]Уважаемый Digitman !
Все заработало, спасибо большое !
Socket.ReceiveBuf (buf^,l);
src.WriteBuffer(buf^,l);
А что означает этот знак ^ ?
SV (2002-11-26 01:07:00) [4]А не проще через апи TransmitFile ;)
dim- (2002-11-25 20:10:00) [5]а клиент ничего не получает, передоваемый размер srcfile.size=800323, что еще можно попробывать сделать
Может есть какой рабочий примерчик?
Digitman (2002-11-25 16:16:00) [6]значит, ничего не ставишь в очередь на передачу.
либо постановка в очередь на передачу всего потока прошла успешно за один вызов SensStream() и весь поток уже ушел к клиенту
dim- (2002-11-25 15:58:00) [7]Будешь смеяться но ServerSocket1ClientWrite стабатывает только в момент конекта, а потом молчит
Digitman (2002-11-25 15:36:00) [8]
> перепутал я
Чего "перепутал"-то ? У тебя передатчик как положено не работает, а ты приемником занялся.
Реализуй сквозную логику передатчика как положено - потом за приемник возьмешься. В неблок.режиме при передаче данных корректная обработка OnWrite() на стороне передатчика О-БЯ-ЗА-ТЕЛЬ-НА !
dim- (2002-11-25 15:27:00) [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 14:54:00) [10]
> на клиенте событие OnClientWrite() даже не наступает.
А с какого хрена оно должно там наступить-то ? Это событие возбуждается тем компонентом, send-функция которого был вызвана.
И, кроме того, однократно - следом же за событием On[Client]Connect, извещая тем самым, что для этого компонента с этого момента можно вызывать Send-методы
Если send-функция (вызванная ГДЕ УГОДНО в неблок.режиме) вернула отказ в той или иной форме (см.хэлп на конкр. send-функцию), нужно "чуть-чуть подождать" и попытаться повторить вызов send-функции в обработчике события On[Client]Write, указав, что следует повторно поместить в очередь передачи.
Во всех противных случаях On[Client]Write не возбуждается.
dim- (2002-11-25 14:38:00) [11]а при ServerSocket1.Socket.Connections[0].SendStream(srcfile);
на клиенте событие OnClientWrite() даже не наступает.
А как проанализировать результат методов SendStream(), SendText()?
Digitman (2002-11-25 12:25:00) [12]Где анализ результатов методов SendStream(), SendText() ?
Где обработка события OnClientWrite() ?
На основании чего предаолагается, что в результате
s:=Socket.ReceiveText;
приемник ВСЕГДА получит в s строчку ИМЕННО в таком виде "srcfile"
dim- (2002-11-25 11:28:00) [13]Люди, а что я сделал не так?
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 11:00:00) [14]Socket.ReceiveBuf (buf^,l);
Reindeer Moss Eater (2002-11-25 10:13:00) [15]Есть встроенный отладчик и пошаговое выполнение кода. Так ты узнаешь строку которая вызывает ошибку.
Андрей_ (2002-11-25 10:09:00) [16]Я уберал эти строки из программы, виндовская ошибка все равно возникае в конце выполнения программы.
Reindeer Moss Eater (2002-11-25 09:06:00) [17]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.