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

Вниз

SendBuf, ReveiveBuf и RECORD...   Найти похожие ветки 

 
Delpher_Gray   (2003-07-14 22:43) [0]

Всем доброго времени суток !
Есть record, его нужно передать с клиента к серверу через TClientSocket и TServerSocket...
Код record"а и функции получения его:
type
TFileInfo = record
Exists: boolean;//true если файл найден
Name: string; //имя файла с расширением
ShortName:string;//DOS 8.3 имя файла
NameNoExt: string;//имя файла без расширения
Extension: string;//расширение файла
AssociatedFile: string;//программа с которой ассоциирован файл
Path: string;// путь к файлу
ShortPath: string;// DOS 8.3 путь файла
Drive: string;// дисковод на котором находится файл
CreateDate: TDateTime; //время когда файл создан
Size: Int64;// размер файла (работает для файлов и больше 2Gb)
Attributes: record //нали?ие/отсутствие системных атрибутов
ReadOnly: boolean;
Hidden: boolean;
System: boolean;
Archive: boolean;
end;
ModifyDate: TDateTime; //время последнего изменения файла
LastAccessDate: TDateTime; //дата последнего открытия
end;

...

function ReadFileInfo(FileName: string): TFileInfo;
var
ts: TSearchRec;

function FileTime2DateTime(FT:_FileTime):TDateTime;
var
FileTime: _SystemTime;
begin
FileTimeToLocalFileTime(FT, FT);
FileTimeToSystemTime(FT,FileTime);
Result := EncodeDate(FileTime.wYear, FileTime.wMonth, FileTime.wDay)+
EncodeTime(FileTime.wHour, FileTime.wMinute, FileTime.wSecond, FileTime.wMilliseconds);
end;

function AssociatedFile(FileExt:string):string;
var
key: string;
begin
with TRegistry.Create do
try
RootKey := HKEY_CLASSES_ROOT;
OpenKey(FileExt, false);
Key := ReadString("");
CloseKey;
OpenKey(key+"\Shell\open\command", false);
Result := ReadString("");
Closekey;
finally
Free;
end
end;

begin
Result.Name := ExtractFileName(FileName);
Result.Extension := ExtractFileExt(FileName);
Result.NameNoExt := Copy(Result.Name,1,length(Result.Name)-length(Result.Extension));
Result.Path := ExtractFilePath(FileName);
Result.Drive := ExtractFileDrive(FileName);
Result.ShortPath := ExtractShortPathName(ExtractFilePath(FileName));
if lowercase(Result.Extension)<>".exe" then Result.AssociatedFile := AssociatedFile(Result.Extension);
if FindFirst(FileName, faAnyFile, ts)=0 then
begin
Result.Exists := true;
Result.CreateDate := FileDateToDateTime(ts.Time);

Result.Size := ts.FindData.nFileSizeHigh*4294967296+ts.FindData.nFileSizeLow;
Result.Attributes.ReadOnly := (faReadOnly and ts.Attr)>0;
Result.Attributes.Hidden := (faHidden and ts.Attr)>0;
Result.Attributes.System := (faSysFile and ts.Attr)>0;
Result.Attributes.Archive := (faArchive and ts.Attr)>0;
Result.ModifyDate := FileTime2DateTime(ts.FindData.ftLastWriteTime);
Result.LastAccessDate := FileTime2DateTime(ts.FindData.ftLastAccessTime);
Result.ShortName := ts.FindData.cAlternateFileName;
Findclose(ts);
end else
( Sender: TObject;
Socket: TCustomWinSocket
)
Всем доброго времени суток !
Есть record, его нужно передать с клиента к серверу через TClientSocket и TServerSocket...
Код record"а и функции получения его:
type
TFileInfo = record
Exists: boolean;//true если файл найден
Name: string; //имя файла с расширением
ShortName:string;//DOS 8.3 имя файла
NameNoExt: string;//имя файла без расширения
Extension: string;//расширение файла
AssociatedFile: string;//программа с которой ассоциирован файл
Path: string;// путь к файлу
ShortPath: string;// DOS 8.3 путь файла
Drive: string;// дисковод на котором находится файл
CreateDate: TDateTime; //время когда файл создан
Size: Int64;// размер файла (работает для файлов и больше 2Gb)
Attributes: record //нали?ие/отсутствие системных атрибутов
ReadOnly: boolean;
Hidden: boolean;
System: boolean;
Archive: boolean;
end;
ModifyDate: TDateTime; //время последнего изменения файла
LastAccessDate: TDateTime; //дата последнего открытия
end;

...

function ReadFileInfo(FileName: string): TFileInfo;
var
ts: TSearchRec;

function FileTime2DateTime(FT:_FileTime):TDateTime;
var
FileTime: _SystemTime;
begin
FileTimeToLocalFileTime(FT, FT);
FileTimeToSystemTime(FT,FileTime);
Result := EncodeDate(FileTime.wYear, FileTime.wMonth, FileTime.wDay)+
EncodeTime(FileTime.wHour, FileTime.wMinute, FileTime.wSecond, FileTime.wMilliseconds);
end;

function AssociatedFile(FileExt:string):string;
var
key: string;
begin
with TRegistry.Create do
try
RootKey := HKEY_CLASSES_ROOT;
OpenKey(FileExt, false);
Key := ReadString("");
CloseKey;
OpenKey(key+"\Shell\open\command", false);
Result := ReadString("");
Closekey;
finally
Free;
end
end;

begin
Result.Name := ExtractFileName(FileName);
Result.Extension := ExtractFileExt(FileName);
Result.NameNoExt := Copy(Result.Name,1,length(Result.Name)-length(Result.Extension));
Result.Path := ExtractFilePath(FileName);
Result.Drive := ExtractFileDrive(FileName);
Result.ShortPath := ExtractShortPathName(ExtractFilePath(FileName));
if lowercase(Result.Extension)<>".exe" then Result.AssociatedFile := AssociatedFile(Result.Extension);
if FindFirst(FileName, faAnyFile, ts)=0 then
begin
Result.Exists := true;
Result.CreateDate := FileDateToDateTime(ts.Time);

Result.Size := ts.FindData.nFileSizeHigh*4294967296+ts.FindData.nFileSizeLow;
Result.Attributes.ReadOnly := (faReadOnly and ts.Attr)>0;
Result.Attributes.Hidden := (faHidden and ts.Attr)>0;
Result.Attributes.System := (faSysFile and ts.Attr)>0;
Result.Attributes.Archive := (faArchive and ts.Attr)>0;
Result.ModifyDate := FileTime2DateTime(ts.FindData.ftLastWriteTime);
Result.LastAccessDate := FileTime2DateTime(ts.FindData.ftLastAccessTime);
Result.ShortName := ts.FindData.cAlternateFileName;
Findclose(ts);
end else
Result.Exists := false;
end;


Как я вычитал в одной статье, record можно передать функцией SendBuf, а вот как именно не написанно :)
И ещё я не могу понять как же его принять потом...
Подскажите плиз как решить эту проблему...

Вродь-бы передать можно так:
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
var
ProgInfo: TFileInfo;
begin
ProgInfo := ReadFileInfo("c:\sc1.bmp");
ClientSocket1.Socket.SendBuf(ProgInfo, SizeOf(ProgInfo));
end;


Если я привёл правильный пример передачи, то подскажите как его принять, если же неправильный, то подскажите как и передать :)

Заранее благодарен !


 
$hade   (2003-07-15 07:47) [1]

ну так же и принимай
ReciveBuf(ProgInfo,SizeOf(ProgInfo))
в чем проблема то?


 
Digitman   (2003-07-15 08:39) [2]


> Delpher_Gray


при наличии в записи полей дин.типа (в дан. случае - string) попытка передачи/приема такой записи прямым SendBuf/ReceiveBuf потерпит фиаско.
дин.типы данных представлены указателями, а передача/прием указателя бессмысленна.
для каждого string-поля необходимо передавать/принимать (теми же SendBuf/ReceiveBuf) префикс длины строки (Length()) и следом же - строковые данные (адрес буфера строковых данных - либо PChar(str) либо @str[1])


 
Delpher_Gray   (2003-07-15 09:41) [3]

2Digitman:
А можно подробнее ?
На конкретном примере ?

2$hade:
При током приёме и передачи, происходит ошибка !
Invalid pointer operation


 
savva   (2003-07-15 09:49) [4]

> Delpher_Gray © (15.07.03 09:41)
> 2Digitman:
> А можно подробнее ?
> На конкретном примере ?
как вариант - сделай строки фиксированнной длинны (такой, как ты думаешь тебе хватит) что то типа
Name: string[MAX_PATH]; //имя файла с расширением

где MAX_PATH в каждом конкретном случае можно заменять чем то своим...


 
$hade   (2003-07-15 09:59) [5]

Сорри! Что-то я не посмотрел структуру...Digitman © (15.07.03 08:39) ессесьно как свегда прав...:-)

Делай как и сказал Digitman или в record"е укажи длину строк:
к примеру
ShortName:string[12];//DOS 8.3 имя файла - все равно оно по определению не будет больше.
ShortPath: string[66];// DOS 8.3 путь файла - 66 - помоему DOS больше не поймет (хотя могу ошибаться)
Extension: string[3]; - в основном так (ну или 4)
ну и так далее.
конечно тут может передаваться немного избыточной инфы (к примеру - имя файла !.! ) но я думаю не большая проблема...


 
Digitman   (2003-07-15 10:33) [6]

механика "правильной" передачи :


TFileInfo = packed record
Exists: boolean;
Name: string;
...
FileSize: Int64;
Attributes: packed record
ReadOnly: boolean;
Hidden: boolean;
System: boolean;
Archive: boolean;
end;
...
ModifyDate: TDateTime; //время последнего изменения файла
end;

...

TMyMemoryStream = class(TMemoryStream)
private
FOnDestroy: TNotifyEvent;
public
constructor Create(OnDestroy: TNotifyEvent);
destructor Destroy; override;
end;

...

var
ms: TMyMemoryStream = nil;
...

constructor TMyMemoryStream.Create(OnDestroy: TNotifyEvent);
begin
inherited Create;
FOnDestroy := OnDestroy;
end;

destructor TMyMemoryStream.Destroy;
begin
if Assigned(FOnDestroy) then
FOnDestroy(Self);
inherited Destroy;
end;

procedure TMyForm.DoOnStreamDestroy(Sender: TObject);
begin
ms := nil;
end;

procedure TMyForm.MySocketWrite(..);
begin
try
Socket.SendStream(ms);
except
ms.Free;
raise;
end;
end;

...

procedure TMyForm.SendFileInfo(FileInfo: TFileInfo);
var
CurPos : Integer;
CurLen: Integer;
begin
if not Assigned(ms) then
ms := TMyMemoryStream.Create(DoOnStreamDestroy);
try
CurPos := ms.Position;
ms.Position := ms.Size;

with ms, FileInfo do
begin
Write(Exists, sizeof(Exists);

CurLen := Length(Name);
Write(CurLen, sizeof(CurLen));
Write(@Name[1], SurLen);

Write(FileSize, sizeof(FileSize));
Write(Attributes, sizeof(Attributes));
Write(ModifyDate, sizeof(ModifyDate));
end;
ms.Position := CurPos;
( ms)
механика "правильной" передачи :


TFileInfo = packed record
Exists: boolean;
Name: string;
...
FileSize: Int64;
Attributes: packed record
ReadOnly: boolean;
Hidden: boolean;
System: boolean;
Archive: boolean;
end;
...
ModifyDate: TDateTime; //время последнего изменения файла
end;

...

TMyMemoryStream = class(TMemoryStream)
private
FOnDestroy: TNotifyEvent;
public
constructor Create(OnDestroy: TNotifyEvent);
destructor Destroy; override;
end;

...

var
ms: TMyMemoryStream = nil;
...

constructor TMyMemoryStream.Create(OnDestroy: TNotifyEvent);
begin
inherited Create;
FOnDestroy := OnDestroy;
end;

destructor TMyMemoryStream.Destroy;
begin
if Assigned(FOnDestroy) then
FOnDestroy(Self);
inherited Destroy;
end;

procedure TMyForm.DoOnStreamDestroy(Sender: TObject);
begin
ms := nil;
end;

procedure TMyForm.MySocketWrite(..);
begin
try
Socket.SendStream(ms);
except
ms.Free;
raise;
end;
end;

...

procedure TMyForm.SendFileInfo(FileInfo: TFileInfo);
var
CurPos : Integer;
CurLen: Integer;
begin
if not Assigned(ms) then
ms := TMyMemoryStream.Create(DoOnStreamDestroy);
try
CurPos := ms.Position;
ms.Position := ms.Size;

with ms, FileInfo do
begin
Write(Exists, sizeof(Exists);

CurLen := Length(Name);
Write(CurLen, sizeof(CurLen));
Write(@Name[1], SurLen);

Write(FileSize, sizeof(FileSize));
Write(Attributes, sizeof(Attributes));
Write(ModifyDate, sizeof(ModifyDate));
end;
ms.Position := CurPos;
MySocket.Socket.SendStream(ms);
except
ms.Free;
raise;
end;
end;




 
Delpher_Gray   (2003-07-15 13:55) [7]

Хех...
В этом куске кода ошибка !!!
with MS, FileInfo do
begin
Write(Exists, sizeof(Exists));

CurLen := Length(Name);
Write(CurLen, sizeof(CurLen));
Write(@Name[1], CurLen); // Ошибки...

Write(FileSize, sizeof(FileSize)); // Ошибки...
Write(Attributes, sizeof(Attributes));
Write(ModifyDate, sizeof(ModifyDate));
end;


Variable required

2DigitMan:
А можешь подсказать как ет всё работает то ???


 
Delpher_Gray   (2003-07-15 13:56) [8]

Алгорит нужен, а то так я и не понял как же всё работает :)


 
Digitman   (2003-07-15 14:15) [9]

Write(Name[1], CurLen); // так правильней

логику OnWrite() я тебе уже изложил - чем не алгоритм ?


 
Digitman   (2003-07-15 14:20) [10]


> Delpher_Gray


Ты ж просил "конкретный пример" - изволь, вот он !)

А теперь получается - поясняй еще и что я тут делаю) ... что называется, "дай г..., дай ложку")))

Пример-то зачем нужен ? чтобы вникнуть в последовательность действий ! и построить в голове стройную схему из обрывков несвязных знаний)


 
Delpher_Gray   (2003-07-15 15:33) [11]

Вродь-бы понял :)
на событие OnWrite посылать MS (если там чё-нить есть), так ?
Я просто подумал нафиг полылать MS в разных кусках кода....


 
Digitman   (2003-07-15 15:45) [12]

еще раз - вникни в логику возникновения события OnWrite() !


 
Delpher_Gray   (2003-07-15 18:26) [13]

А потом принять это можно будет через ReceiveBuf и записатьв record ???


 
Digitman   (2003-07-16 08:32) [14]

да, разумеется



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

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

Наверх




Память: 0.5 MB
Время: 0.008 c
1-58624
Abikos
2003-09-05 15:14
2003.09.18
Как переключится в окно ???


6-58798
Noro
2003-07-17 22:06
2003.09.18
Передача данных: Клиент-Сервер, Сервер-Клиент


4-58977
Bill
2003-07-18 16:06
2003.09.18
Перевод строки в число с плавающей точкой


1-58731
Андрей Слюсаренко
2003-09-07 11:43
2003.09.18
Всплывающее меню


1-58762
Ghost
2003-09-06 13:37
2003.09.18
Не могу понять в чем ошибка :(





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский