Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

передача большого файла через 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=0&#entry1656824), что нужно использовать 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]

> где я делаю не правильно
вот тут
> \\далее вылетает ошибка
она хочет в Самарканд а ту ее в Воркуту... вот она вылетает, вылетает, а вылететь не может.


Наверх

Титульная страница Поиск, карта сайта Написать письмо