Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2002.09.23;
Скачать: [xml.tar.bz2];

Вниз

Как мне узнать имя файла отправл. с СlientSocket в ServerSocket   Найти похожие ветки 

 
OlegG   (2002-07-12 23:17) [0]

Подскажите, как мне узнать имя файла отправленного с СlientSocket и сохранить принятые данные в файл под тем же именем на машине, где стоит ServerSocket


 
SerVS   (2002-07-13 00:53) [1]

Что именно тебе не понятно? Ну неужели можно садиться писать сетевое приложение, если не понимаешь вообще как надо писать программы...
Ты вообще слышал о таком понятии как "протокол"? Так, открою секрет, это не что старшное и непонятное, а "соглашание". В данном случае "о формате передаваемое и получаемой информации". Сокеты это просто транспорт, а ты надо разработать протокол прикладного уровня. И в дальнейшем ему следовать.
Это не так страшно ;), вот пример такого протокола.
Передача:
1) Длина заголовка
2) Загаловок
1. Имя файла
2. Аттрибуты
3. Длина
4. сюда можешь еще что-то написать, например контрольную сумму
3) Данные.
Вот сообственно и все. Теперь Клиент знает что ему посылать, а сервер что принимать.

ЗЫ. Если свое лень придумавать, используй FTP, или мой пример. ;)


 
OlegG   (2002-07-13 10:47) [2]

Я конечно понимаю, что вы все знаете и умеете, но мне набор умных фраз не поможет. Если можно на примере.Я только начинаю разбираться с дельфи.


 
Anatoly Podgoretsky   (2002-07-13 11:52) [3]

Вряд ли тогда поможет пример, примем за аксиому, что ты можешь передавать с помощью вышеуказанных компонент, а иначе твой вопрос вообще не имеет смысла, то тебе всего лишь нужно сначала передать имя, а затем сам файл, как ты понимаешь передача имени не отличается от передачи любых других данных.


 
Malder   (2002-07-13 12:52) [4]

Человеку нужен исходный код передачи файла...

OlegG, если хочешь, чтобы помогли - задавай конкретный вопрос.
Типа, делаю то и то, а получается вовсе не то.

А вопрос твой некорректный. Вроде тебе понятно как передавать сам файл, а как передать имя файла непонятно. Странно, не правда ли ? Вот и сиди, гадай, что человеку конкретно не ясно...


 
OlegG   (2002-07-13 21:20) [5]

Спасибо Malder, поправка справедливая. Вот код:

procedure TForm1.Button1Click(Sender: TObject);
Var
S : String;
Strm : TfileStream;
begin
{Получаю имя файла}
S:= ExtractFileName(ExpandFileName(OpenDlg.fileName));
{Передаю имя}
clientSocket1.Socket.SendText(s);
{Читаю данные в поток}
Strm:= TFileStream.create(OpenDlg.FileName,fmOpenRead);
{Отправляю поток}
clientSocket1.Socket.SendStream(Strm);
Strm.Free;
{Вопрос первый: когда вызываю Strm.Free выдается ошибка. Почему?}
end;

Вопрос второй: вот примерный код получения потока на стороне сервера. Как мне выделить имя файла из полученного потока.

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var bufsize:integer;
buffer:pchar;
str:TFileStream;
NameFile : String;
begin
NameFile := ??????????????????????????????
bufsize:=Socket.ReceiveLength;
GetMem(buffer,bufsize);
Socket.ReceiveBuf(buffer^,bufsize);
try
str:=TFileStream.Create("C:\resive\"+ NameFile,fmOpenWrite);
except
str:=TFileStream.Create("C:\resive\"+ NameFile,fmCreate);
end;
str.Seek(0,soFromEnd);
str.WriteBuffer(buffer^,bufsize);
FreeMem(buffer);
str.Free;
end;
end;
end;



 
SerVS   (2002-07-14 00:21) [6]

а NameFile := ReceiveText попробывать не пытался?
ЗЫ. Имхо понятнее и надежнее чем я напиал придумать сложно...


 
OlegG   (2002-07-14 09:16) [7]

Пробовал, но ReceiveText принимает полностью поток(имя+все данные отправленного потока), и мне надо из него выделить имя файла.


 
Anatoly Podgoretsky   (2002-07-14 13:25) [8]

Проблема выделения может решать предопределенным ограничителем, наприме #0, cr, lf, рекомендую последнии два, как пару #13#10


 
Malder   (2002-07-14 23:42) [9]

Ага. Передавай имя файла, потом спец. код, потом уже само содержимое файла.
Соответственно, при приеме ищи спец. код и все, что до него - это имя файла...


 
OlegG   (2002-07-15 02:16) [10]

Спасибо за совет, но возникла новая проблема:
Как удалить из буфера ограничитель, и переопределить размер буфера. Вот мой код
.....
var Na : String;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var bufsize:integer;
buffer:pchar;
str:TFileStream;
I : Integer;
begin
bufsize:=Socket.ReceiveLength;
GetMem(buffer,bufsize);
Socket.ReceiveBuf(buffer^,bufsize);
I:=0;
Repeat
I:=Pos("#13#10",PChar(buffer)); {Ищем разделитель}
if I<>0 then {Если найден делитель, тогда ... }
Begin
Na:=Copy(PChar(Buffer),1,I-1);{Копируем имя файла в переменную}
????????????????? {Убрать делитель из буфера}
????????????????? {Переопределить размер буфера}
end;
Until I =0;
try
str:=TFileStream.Create("C:\resive\"+Na,fmOpenWrite);
except
str:=TFileStream.Create("C:\resive\"+Na,fmCreate);
end;
str.Seek(0,soFromEnd);
str.WriteBuffer(buffer^,Bufsize);
FreeMem(buffer);
str.Free;
end;
end;


 
OlegG   (2002-07-15 10:35) [11]

АУ, Мастера, вы где?


 
Digitman   (2002-07-15 12:06) [12]

Почему у тебя на Strm.Free исключение возникает ?

Открываем хэлп, в нем - черным по белому написано :

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.


По поводу всего остального - не все так просто. Поточный режим работы гнезда требует реализации машины состояния. Почитай хотя бы для начала все ветки обсуждений в этом форуме, касающиеся гнездовой поточной трансляции данных.


 
OlegG   (2002-07-15 15:33) [13]

Люди, читал я FAQ и литературку всякую, но мне от этого не легче. Неужели никто из вас не сталкивался с проблеммой пересылки файлов по сокетам? ПОМОГИТЕ!!!!!!!!!!!!!!!!!!!!!!
Нужен пример!!!!!!!!!!!!!!!!!!!!


 
Digitman   (2002-07-15 16:43) [14]

Не надо так громко кричать)
По "сокетам" не файлы передаются ... и не картинки или еще чего-то там наподобие ...

Передается просто поток двоичной информации из некоего буфера, логическую структуру которого ты можешь и должен предусмотреть самостоятельно.

Прекрасный пример трансляции структурированных блоков данных есть в демо-проекте scktsrvr.dpr, там же найдешь и пример реализации машины состояния приемника. Минимальная переработка - и твоя задача как на ладони, реализованная не в самом худшем алгоритме


 
alexta   (2002-07-16 21:00) [15]

>2 OlegG
Я бы тебе посоветовал посроить передачу файла иным образом. Сначала передавать структуру с информацией о файле. После получения структуры послать своему серверу подтверждение принятия записи. Потом передавать сам файл. Так ты избавишся от неопределенности по поводу длины имени файла. Вот пример кода для клиента, для сервера аналогично:

const
AllRight = 0;
SCM_Init = 1;
SCN_Started = 2;

type
AnswerRec = record
FileName: string[100];
Size: integer;
end;

var
Request: byte;
Answer: AnswerRec;
MemStream: TMemStream; // глобальные переменные
_lastcommand: byte;
FileName: string;
Size: integer;
Client: TClientSocket;

procedure ClientRead(Sender: TObject,Socket: TWinCustomSocket);
begin
case _lastcommand of
SCM_Init : begin
len:=Socket.ReceiveLength;
GetMem(Buf,len);
len:=Socket.ReceiveBuf(Buf^,len);
if (MemStream = nil) then
MemStream:=TMemoryStream.Create
else
MemStream.Seek(0,soFromEnd);
MemStream.Write(Buf^,len);
MemStream.Seek(0,soFromBeginning);
if (MemStream.Size >= sizeof(AnswerRec)) do
begin
MemStream.Read(AnswerRec,sizeof(AnswerRec));
FileName:=AnswerRec.FileName;
Size:=AnswerRec.Size;
Request:=AllRight;
Socket.SendBuf(Request,sizeof(Request));
_lastcommand:=SCM_Started;
MemStream.Free;
MemStream:=nil;
end;
end;

SCM_Started : begin
len:=Socket.ReceiveLength;
GetMem(Buf,len);
len:=Socket.ReceiveBuf(Buf^,len);
AssignFile(f,FileName);
if (FileExists(FileName)) then
try
FileSetAttr(FileName,0);
Reset(f,1);
except
on EInOutError do
begin
if Assigned(fOnError) then
fOnError(self,AccessFileError);
FreeMem(Buf);
Client.Close;
Exit;
end;
end
else
try
rewrite(f,1);
except
on EInOutError do
begin
if Assigned(fOnError) then
fOnError(self,CreateFileError);
FreeMem(Buf);
Client.Close;
Exit;
end;
end;
Seek(f,FileSize(f));
if (len < size-FileSize(f)) then
BlockWrite(f,Buf^,len);
else
begin
len:=size-FileSize(f);
BlockWrite(f,Buf^,len);
if Assigned(fOnGetFile) then
fOnGetFile(self,_transferefileinfo.name);
Client.Close;
end;
CloseFile(f);
FreeMem(Buf);
end;
end;


 
OlegG   (2002-07-20 23:47) [16]

Спасибо огромное всем, кто помог разобраться с данным вопросом не умными фразами, а конкретным примером.
Я уже докопался сам.



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

Форум: "Сети";
Текущий архив: 2002.09.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.5 MB
Время: 0.007 c
1-73667
Yaro
2002-09-12 09:32
2002.09.23
CopyMemory - ограничена по сайзу?


3-73506
Андрей Дмитриев
2002-09-02 07:56
2002.09.23
Как сжать базу MS Access...


3-73530
DeepProg
2002-08-29 18:56
2002.09.23
I hate OnCalcFields


3-73480
Morgan3212
2002-08-27 16:13
2002.09.23
БД


1-73659
silenser
2002-09-11 17:41
2002.09.23
Окна





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский