Форум: "Сети";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
ВнизIdTCPServer vs IdTCPClient висят?? Найти похожие ветки
← →
Sanya-spb (2003-11-24 16:20) [0]Добрый день(вечер)
как обычно... есть клиент, и есть сервак...
клиент:
берет файл, сжимает его, пакует в Stream вместе с доп инфой и шлет на сервер, ждет с сервака CRC и т.д. все сначала для другого файла...
сервер:
принимает stream, распаковывает, считает его CRC, отсылает CRC обратно,...
проблема в следующем: когда передаю большой файл, то после (успешного!!) приема первого файла все это хозяйство впадает в кому... (смотрю по процессорному датчику...) ни ошибок, ни чего... просто спим... щас покажу где...
===== Сервер (судя по логу с ним все в порядке): ======
if Command="UPLOAD"
then begin
inc(CurClient.UploadCMD);
Params:=TStringList.Create;
try ExtractParams(Line,Params);
Path:=Params.Values["path"];
Size:=Cardinal(StrToInt(Params.Values["size"]));
log("Upload: path=""+Path+"", Stream size="+Params.Values["size"],CurClient.LogFile);
finally Params.Free; end;
Path:=TCPRoot+SlashToBackSlash(Path);
if FileExists(Path) then log("-- File exists! I""ll rewrite it",CurClient.LogFile);
CompressedStream:=TMemoryStream.Create; log("++ Ok. Getting Stream ...",CurClient.LogFile);
try while (CompressedStream.Size<Size) and AThread.Connection.Connected
do begin
AThread.Connection.ReadBuffer(Buffer,1);
CompressedStream.Write(Buffer,1);
end;{}
if CompressedStream.Size=Size
then begin{} log("++ Ok. Extracting UnpackSize and CRC from stream...",CurClient.LogFile);
CompressedStream.Position:=0;
CompressedStream.Read(UnpackSize,SizeOf(UnpackSize));
CompressedStream.Read(strHashValue,SizeOf(strHashValue)); log("++ Ok. Decompressing...",CurClient.LogFile);
ZStream:=TDecompressionStream.Create(CompressedStream);
try FileStream:=TFileStream.Create(Path, fmCreate or fmOpenWrite or fmShareExclusive);
try if UnpackSize>0
then FileStream.CopyFrom(ZStream,UnpackSize); log("++ Ok. Generating CRC...",CurClient.LogFile);
IdHashCRC32:=TIdHashCRC32.Create;
try FileStream.Position:=0;
HashValue:=IdHashCRC32.HashValue(FileStream); log("++ Ok. Send CRC to Client",CurClient.LogFile);
AThread.Connection.WriteBuffer(HashValue,SizeOf(HashValue)); log("++ Ok. Free memory and Check CRC...",CurClient.LogFile);
finally IdHashCRC32.Free; end;
finally FileStream.Free; end;
if strHashValue<>HashValue
then begin
log("-- Bad CRC!! Removing file ""+Path+"" to BUGs",CurClient.LogFile);
if not MoveFile(PChar(Path),PChar(TCPRoot+"\BUGs\"+ExtractFileName(Path)))
then log("-- Can""t remove bad file ""+Path+""",CurClient.LogFile);
end;
finally ZStream.Free; end;
log("++ Ok.",CurClient.LogFile);
inc(CurClient.UploadOk);
end else begin
log("-- Bad Stream.Size",CurClient.LogFile);
end;{}
finally CompressedStream.Free; end;
end else if Command="MKDIR" ...
==================================
=========== Клиент (а вот по его логу видно что спит он на приеме CRC от сервера): ===============
function TService_ArisClient.Upload(localPath, toPath: string): integer;
var
FileStream: TFileStream;
CompressedStream: TMemoryStream;
ZStream: TCompressionStream;
IdHashCRC32: TIdHashCRC32;
UnpackSize: Cardinal;
HashValue: Cardinal;
servHashValue: Cardinal;
CompressionRate: single;
begin
Log("UPLOAD: ""+localPath+"" -> ""+toPath+""");
CompressedStream:=TMemoryStream.Create;
try
FileStream:=TFileStream.Create(localPath,fmOpenRead or fmShareDenyWrite);
try
IdHashCRC32:=TIdHashCRC32.Create;
try
FileStream.Position:=0;
HashValue:=IdHashCRC32.HashValue(FileStream);
finally
IdHashCRC32.Free; end;
FileStream.Position:=0;
UnpackSize:=FileStream.Size;
CompressedStream.Write(UnpackSize,SizeOf(UnpackSize));
CompressedStream.Write(HashValue,SizeOf(HashValue));
ZStream:=TCompressionStream.Create(clMax,CompressedStream);
try
ZStream.CopyFrom(FileStream,FileStream.Size);
CompressionRate:=ZStream.CompressionRate;
finally ZStream.Free; end;
Result:=FileStream.Size;
finally
FileStream.Free; end;
IdTCPClient.WriteLn("UPLOAD"#32"path="+toPath+#32"size="+IntToStr(CompressedStream.Size));
log("++ Compression rate="+FloatToStrF(CompressionRate,ffFixed,18,2));
CompressedStream.Position:=0; log("++ Open Write Buffer");
IdTCPClient.OpenWriteBuffer(); log("++ Ok. Sending Sream...");
IdTCPClient.WriteStream(CompressedStream); log("++ Ok. Close Write Buffer");
IdTCPClient.FlushWriteBuffer(); log("++ Ok. Flush Write Buffer");
IdTCPClient.CloseWriteBuffer; log("++ Ok. Free Compressed Stream");
finally
CompressedStream.Free; end; log("++ Ok. Get CRC");
// тут мы спим????
IdTCPClient.ReadBuffer(servHashValue,SizeOf(servHashValue)); log("++ Ok. Check CRC");
if HashValue=servHashValue
then begin
log("++ Ok");
end else begin
Result:=-1;
log("-- CRC Error");
end;
end;
=======================================
почему???
← →
Reindeer Moss Eater (2003-11-24 16:24) [1]Потому что с сервера не приходит CRC
← →
Sanya-spb (2003-11-24 16:26) [2]но сервер же отправляет его...
AThread.Connection.WriteBuffer(HashValue,SizeOf(HashValue));
← →
Reindeer Moss Eater (2003-11-24 16:27) [3]Вот это зачем?
IdTCPClient.FlushWriteBuffer(); log("++ Ok. Flush Write Buffer");
IdTCPClient.CloseWriteBuffer;
← →
Reindeer Moss Eater (2003-11-24 16:28) [4]// тут мы спим????
IdTCPClient.ReadBuffer(servHashValue,SizeOf(servHashValue));
SizeOf(servHashValue) равна длине CRC?
← →
sanya-spb (2003-11-24 16:29) [5]очистить буфер и закрыть... он пока не нужен, а данные должны передаться, а что не надо?
← →
sanya-spb (2003-11-24 16:30) [6]SizeOf(servHashValue) равна длине CRC?
да
← →
Reindeer Moss Eater (2003-11-24 16:30) [7]очистить буфер и закрыть... он пока не нужен,
Кому не нужен?
а данные должны передаться, а что не надо?
Все данные на этот момент уже переданы
← →
Reindeer Moss Eater (2003-11-24 16:31) [8]SizeOf(servHashValue) равна длине CRC?
да
Скока в граммах?
← →
sanya-spb (2003-11-24 16:34) [9]SizeOf(servHashValue) = 32bit
========= серверный var ==========
var
Line: string;
Command: string;
Params: TStrings;
Path: string;
Size: Cardinal;
UnpackSize: Cardinal;
FileStream: TFileStream;
CompressedStream: TMemoryStream;
TMPStream: TMemoryStream;
ZStream: TCustomZlibStream;
LS: TStringStream;
IdHashCRC32: TIdHashCRC32;
HashValue: Cardinal;
strHashValue: Cardinal;
Buffer: byte;
CurClient: PClient;
==================================
← →
sanya-spb (2003-11-24 16:36) [10]>>очистить буфер и закрыть... он пока не нужен,
>>Кому не нужен?
>>а данные должны передаться, а что не надо?
>>Все данные на этот момент уже переданы
хорошо... убераю все эти буфера
// IdTCPClient.OpenWriteBuffer(); log("++ Ok. Sending Sream...");
IdTCPClient.WriteStream(CompressedStream); log("++ Ok. Close Write Buffer");
// IdTCPClient.FlushWriteBuffer(); log("++ Ok. Flush Write Buffer");
// IdTCPClient.CloseWriteBuffer;
===========================
ничего.....
← →
Reindeer Moss Eater (2003-11-24 16:36) [11]Да уже увидел, что равны.
Значит клиент ждет 4 байта CRC и никак не может дождаться.
Другой причины не вижу.
← →
sanya-spb (2003-11-24 16:38) [12]на маленьких файликах до 500KB все работает, по поры до времени, пока опять же не подвиснет в том же месте
← →
Reindeer Moss Eater (2003-11-24 16:38) [13]Так, так, так.
А где серверу сообщается длина оригинального несжатого стрима?
← →
sanya-spb (2003-11-24 16:40) [14]>>А где серверу сообщается длина оригинального несжатого стрима?
UnpackSize:=FileStream.Size;
CompressedStream.Write(UnpackSize,SizeOf(UnpackSize));
← →
Reindeer Moss Eater (2003-11-24 16:55) [15]А локально (на одной машине) работает устойчиво?
← →
sanya-spb (2003-11-24 16:57) [16]в том то и дело что НЕТ... ни локально ни удаленно
← →
Reindeer Moss Eater (2003-11-24 17:03) [17]Странно.
В алгоритме никаких явных засад не видно.
Разве что побайтовое чтение мне не нравится, но это дело вкуса.
← →
sanya-spb (2003-11-24 17:08) [18]побайтовое это для отлова багов типа disconnect, но дело не в этом...
а на уровне сокетов подобная задержка (>20сек) может влиять? там ничего не отмирает, пока сервер распаковывает стрим?
← →
Reindeer Moss Eater (2003-11-24 17:10) [19]А чем побайтовое чтение полезнее блочного чтения при отлове дисконнекта?
← →
sanya-spb (2003-11-24 17:14) [20]ни чем, просто руки не дошли... сначала с багами разберусь, потом буду оптимизировать
← →
sanya-spb (2003-11-25 10:25) [21]ночьку поковырялся и пришел к такому:
если на клиенте после отправки стрима и перед приемом CRC поставить задержку... то все идеально... но, вы понимаете, господа, что это не решение
для теста я директорию с MP3шками гонял - файлы по 3..6 метров
========================
IdTCPClient.WriteStream(CompressedStream); log("++ Ok. Close Write Buffer");
Sleep(30000); // вот это дало толчок для работы
========================
проблема в том что файлов передаваться будет много, и размеры у них разные... может что посоветуете? спасибо
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.008 c