![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
передача большого файла через Socket [D5, XP]
loki3d © (2011-04-15 19:10:00)помогите разбраться, почему не получается передать файл.
Я следую примеру в FAQ
http://www.delphisources.ru/pages/faq/base/sockets_in_delphi.html
в частности пытаюсь реализовать вот эту часть
{Посылка файла через сокет}
procedure SendFileBySocket(filename: string);
var srcfile: TFileStream;
begin
{Открываем файл filename}
srcfile := TFileStream.Create(filename, fmOpenRead);
{Посылаем его первому подключенному клиенту}
ServerSocket1.Socket.Connections[0].SendStream(srcfile);
{Закрываем файл}
srcfile.Free;
end;
++++++++++++++++++++++++++++
Прием файла через сокет}
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
l: Integer;
buf: PChar;
src: TFileStream;
begin
{Записываем в l размер полученного блока}
l := Socket.ReceiveLength;
{Заказываем память для буфера}
GetMem(buf,l+1);
{Записываем в буфер полученный блок}
Socket.ReceiveBuf(buf,l);
{Открываем временный файл для записи}
src := TFileStream.Create('myfile.tmp',fmOpenReadWrite);
{Ставим позицию в конец файла}
src.Seek(0,soFromEnd);
{Записываем буфер в файл}
src.WriteBuffer(buf,l);
{Закрываем файл}
src.Free;
{Освобождаем память}
FreeMem(buf);
end;
я пытась повторить пример с той лиш разницей, что у меня Клиент передает файл серверу.
procedure TForm1.Button2Click(Sender: TObject);
var
srcfile: TFileStream;
begin
srcfile := TFileStream.Create('Путь до файла', fmOpenRead);
Form1.ClientSocket1.Socket.SendStream (srcfile);
srcfile.Free;
end;
попытка приема файла
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
VAR
l: Integer;
buf: PChar;
src: TFileStream;
begin
l := form1.ServerSocket1.Socket.ReceiveLength;
GetMem(buf,l+1);
Form1.ServerSocket1.Socket.ReceiveBuf (Buf,l);
\\далее вылетает ошибка
src := TFileStream.Create('D:\myfile.tmp',fmOpenReadWrite);
src.Seek(0,soFromEnd);
src.WriteBuffer(buf,l);
src.Free;
FreeMem(buf);
end;
Ткните носом пожалуйста, где я делаю не правильно
Slym (2011-04-18 06:39:00) [1]Блокирующий режим сокетов для новичков понятней... переделай в блок
sniknik (2011-04-17 11:17:00) [2]c0000008 - неверный дескриптор.
возможно даже buf^ неправильно (или один правильно другой нет), т.к. зависит от того, что функцией ожидается, т.е. как описан входной параметр, или отсутствие соединения и соответственно не инициализированность какого нибудь обьекта который на соединении создается... смотря где это происходит.
loki3d (2011-04-17 08:56:00) [3]Socket.ReceiveBuf (buf^,l);
src.WriteBuffer(buf^,l);
все равно не работает
приложение или зависает или выдает
EExternalException with message 'External exception c0000008'
MBo (2011-04-16 19:25:00) [4]разыменование:
ReceiveBuf(buf^,
Вариант (2011-04-16 19:13:00) [5]
> loki3d (16.04.11 18:17) [9]
Socket.ReceiveBuf (buf,l);
А вот об этом писал
> MBo © (15.04.11 22:55) [5]
Кстати и в других местах кода та же проблема
loki3d (2011-04-16 18:33:00) [6]
> Забыл приконнектиться к серверу? (или не дождался этого
> радостного события)
нет, меня клиент оуществляет подключение к серверу.
а при передаче потока на приеме в качестве теста я пробовал принимать текст и получал Мусор, читаемый из файла.
так что тут все нормально ИМХО
Вариант (2011-04-16 18:19:00) [7]
> loki3d (16.04.11 09:57) [7]
Забыл приконнектиться к серверу? (или не дождался этого радостного события)
loki3d (2011-04-16 18:17:00) [8]sniknik, Ок. поискал по тексту ошибки решения.
Пишут ( http://forum.sources.ru/index.php?showtopic=198066&st=0entry1656824), что нужно использовать Socket.ReceiveBuf вместо ServerSocket1.Socket.ReceiveBuf
Сделал. изначальная ошибка исчезла.
появилась следующая при обработке строки
src := TFileStream.Create('D:\myfile.tmp',fmOpenReadWrite);
что файл не существует и не может быть открыт.
в итоге внесенных изменений процедура стала выглядеть так
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
VAR
l: Integer;
buf: PChar;
src: TFileStream;
begin
l := Form1.ServerSocket1.Socket.ReceiveLength;
GetMem(buf,l+1);
Socket.ReceiveBuf (buf,l);
If Not FileExists('D:\myfile.tmp') then
begin
src := TFileStream.Create('D:\myfile.tmp',fmCreate);
end else
begin
src := TFileStream.Create('D:\myfile.tmp',fmOpenReadWrite);
end;
src.Seek(0,soFromEnd);
src.WriteBuffer(buf,l);
src.Free;
FreeMem(buf);
Теперь данная процедура отрабатывает один раз на пошаговой обработке и сваливается в ошибку на строке Socket.ReceiveBuf (buf,l), когда она обрабатывается второй раз.
Project Project1.exe raised exception class EExternalException with message 'External exception c0000008'
sniknik (2011-04-16 10:27:00) [9]> no address was supplied (10057) оn API 'recv''
нет адреса, посылка "на деревню дедушке".
loki3d (2011-04-16 09:57:00) [10]Inovet, виноват.
Вот содержание ошибки
Project Project1.exe raised exception class ESocketError with message 'Windows socket error: Запрос на отправку или получение данных (When sending on a datagram socket using a sendto call) no address was supplied (10057) оn API 'recv''.
MBo, если я праивльно понял описание нетипизированных переменных, то у меня "Buf" объявлен как PChar, т.е. тип указан.
Но могу ошибаться, т.к. мало в этом понимаю.
Германн (2011-04-16 04:14:00) [11]
> Я следую примеру в FAQ
> http://www.delphisources.ru/pages/faq/base/sockets_in_delphi.
> html
Похоже сей пример явно неправильный.
MBo (2011-04-15 22:55:00) [12]Как объявлен первый параметр у ReceiveBuf?
Если нетипизированный var, то указательный тип (PChar) надо разыменовать
Inovet (2011-04-15 22:43:00) [13]> [2] loki3d (15.04.11 21:30)
> спасибо за содержательный ответ.
Тебе же намекают, что телепаты в отпуске. Какая ошибка? Где точный текст сообщения о ней?
sniknik (2011-04-15 22:25:00) [14]да не за что. спрашивайте еще... только содержательно.
loki3d (2011-04-15 21:30:00) [15]спасибо за содержательный ответ.
sniknik (2011-04-15 20:16:00) [16]> где я делаю не правильно
вот тут
> \\далее вылетает ошибка
она хочет в Самарканд а ту ее в Воркуту... вот она вылетает, вылетает, а вылететь не может.