![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
проблема с большими числами [D7, XP]
_ant_ © (2007-11-20 15:15:00)проблема в следующем:
клиент-сервер. клиент отправляет серверу длину массива, который он хочет получить. сервер забивает массив и отправляет его через tcp/ip.
для длины<90 000 работает, если задать длину >100 000, то перестает работать.
не подскажите из-за чего может не работать?
может с массивом надо по другому работать?
пару команд, как работает.
//сервер
readinteger(maslength);
setlength(pocket,maslength);
забивается массив из файла
writeBuffer(Pocket[0],length(Pocket));
//клиент
writeinteger(maslength);
setlength(pocket,maslength);
ReadBuffer(Pocket[0],length(Pocket));
записывается массив в файл
_ant_ (2007-11-21 11:07:00) [1]вот это я ...
заработало, как надо.
спасибо, Slym
Slym (2007-11-21 10:59:00) [2]так и есть!
psnCRC32.CRC32Full(sdp.df [0],maslength) ;
_ant_ (2007-11-21 10:53:00) [3]//вызов из программы
sdp.CRC_32:=psnCRC32.CRC32Full(sdp.df,maslength) ;
//вызов в модуле psnCRC32
function CRC32Full(const Data; const Count: Cardinal): Cardinal;
begin
//Result:= not 0;
CRC32Next(Data, Count, Result);
Result:= not Result;
end;
sdp.DF:array of byte;
Slym (2007-11-21 10:36:00) [4]складывается впечатление что CRC32Next неправильно параметры передаешь а именно параметр Data...
строку вызова CRC32Next давай
_ant_ (2007-11-21 10:29:00) [5]спасибо за корректировки.
но тем не менее, все равно возникает ошибка на 93565 шаге вычисления.
(procedure CRC32Next вставил как было написано Slym-ом)
Slym (2007-11-21 10:24:00) [6]MyCRC32 and $FF - лишнее
хватит byte(MyCRC32)
T[byte(byte(byte(MyCRC32) xor PData^))];
Slym (2007-11-21 10:11:00) [7]Сергей М. © (21.11.07 9:54) [20]
Значит ошибка не в этой строке
ошибка в том что компилятор при операции
T[MyCRC32 and $FF xor PData^];
индексом к таблице T принимает полный регистр (EAX) а не его младшую часть (AX)
нужно явно указывать диапазон T[byte(MyCRC32 and $FF xor PData^)]; тогда перед использованием индекса его обрубятXOR EAX, $000000FFдо границ байта
Сергей М. (2007-11-21 09:54:00) [8]
> не ловится
Значит ошибка не в этой строке, а как всегда в 17-й
Slym (2007-11-21 09:30:00) [9]исправлено и немного оптимизировано по скорости
procedure CRC32Next(const Data; const Count: Cardinal; var CRC32: Cardinal);
var
PData: PByte;
I,MyCRC32: Cardinal;
begin
if Count=0 then exit;
PData:= @Data;
I:=Count;
MyCRC32:= CRC32;
repeat
MyCRC32:= MyCRC32 shr 8 xor T[byte(byte(MyCRC32) xor PData^)];
Inc(PData);
Dec(I);
until I=0;
CRC32:= MyCRC32;
end;
Плохиш (2007-11-20 17:29:00) [10]
> все равно выводится, приведенная выше ошибка и все.
Детский сад. F7/F8/F9 нажимать Пушкин должен?
_ant_ (2007-11-20 17:11:00) [11]не ловится. писал так и еще вместо EAccessViolation, просто exception
все равно выводится, приведенная выше ошибка и все.
опытным путем установил, что ошибка возникает на 93565 шаге
Сергей М. (2007-11-20 16:49:00) [12]
> как проверить?
Вот так:
try
MyCRC32:= MyCRC32 shr 8 xor T[MyCRC32 and $FF xor PData^];
except
on e: EAccessViolation do ShowMessage('Грабли на ' + IntToStr(i) + '-ой итерации цикла);
raise;
end;
_ant_ (2007-11-20 16:35:00) [13]var T: array [byte] of Cardinal; -
это матрица заполняется ранее.алгоритмом, в ней не должно быть проблем. увеличение элементов ничего не дает, да и по смыслу не нужно.
вся процедура:
procedure CRC32Next(const Data; const Count: Cardinal; var CRC32: Cardinal);
var
MyCRC32, I: Cardinal;
PData: ^Byte;
begin
PData:= @Data;
MyCRC32:= CRC32;
for I:= 1 to Count do begin
MyCRC32:= MyCRC32 shr 8 xor T[MyCRC32 and $FF xor PData^];
Inc(PData);
end;
CRC32:= MyCRC32;
end;
вылез или нет не знаю. повторюсь, а как проверить?
p.s. если убрать вычисление crc32, то все работает.
clickmaker (2007-11-20 16:18:00) [14]
> T[MyCRC32 and $FF xor PData^];
вылез за границы массива?
_ant_ (2007-11-20 16:17:00) [15]ругается при вычислении crc32
на след. строчку:
//при первом способе вычисления
MyCRC32:= MyCRC32 shr 8 xor T[MyCRC32 and $FF xor PData^];
//при втором способе вычисления
mov edx,[esi]
Project Server.exe raised exception class EAccessViolation with message 'Access violation at address 0046F792' in module 'Server.exe'. Read of address 0048C000'. Process stopped
вот
Сергей М. (2007-11-20 16:04:00) [16]Нужно вооружиться встроенным отладчиком и оттрассировать пошагово строки между try и except
_ant_ (2007-11-20 15:52:00) [17]знал бы, не утаил бы эту информацию.
а как это узнать? что нужно переделать?
Сергей М. (2007-11-20 15:49:00) [18]
> гы
И какая конкретно строчка в этом "гы" вызывает исключение ?
_ant_ (2007-11-20 15:45:00) [19]гы, вот что там находится:
WriteLn(LCommand);
case cboCommands.ItemIndex of
0: LInString := ReadLn;
1: LInString := ReadLn;
2: LInInteger := ReadInteger;
3: LInString := ReadLn;
4: LInString := ReadLn;
end;
if LInInteger <> -1 then
LInString := IntToStr(LInInteger);
if cboCommands.ItemIndex<>5 then begin
lbCommunication.Items.Insert(0,'We said -> ' + LCommand);
lbCommunication.Items.Insert(0,'Server said -> ' + LInString);
end ;
//вот здесь отправляется команда на получение массива
if cboCommands.ItemIndex=5 then begin
lbCommunication.Items.Insert(0,'We said -> ' + LCommand);
AssignFile(tfile,edit2.Text);
reset(tfile);
writeinteger(maslength);
setlength(sdp.DF,maslength);
setlength(pocket,maslength+12);
ReadBuffer(Pocket[0],length(Pocket));
SDP.n:=Getinteger(Pocket,0);
SDP.l:=Getinteger(Pocket,4);
SDP.crc_32:=Getinteger(Pocket,maslength+8);
for i:=8 to maslength+7 do
sdp.DF[i-8]:=pocket[i];
dzapis(maslength);
lbCommunication.Items.Insert(0,'server said -> Bufer prinyat' ) ;
lbCommunication.Items.Insert(0,'We said -> n = ' + inttostr(sdp.n));
lbCommunication.Items.Insert(0,'We said -> l = ' + inttostr(sdp.l));
lbCommunication.Items.Insert(0,'We said -> crc_32 = ' + inttostr(sdp.CRC_32));
crc_32:=$ffffffff;
crc_32:=crc32.CalculateCRC32(sdp.df,maslength );
lbCommunication.Items.Insert(0,'We said -> crc_32 = ' + inttostr(crc_32));
closefile(tfile);
end;
_ant_ (2007-11-20 15:45:00) [20]гы, вот что там находится:
WriteLn(LCommand);
case cboCommands.ItemIndex of
0: LInString := ReadLn;
1: LInString := ReadLn;
2: LInInteger := ReadInteger;
3: LInString := ReadLn;
4: LInString := ReadLn;
end;
if LInInteger <> -1 then
LInString := IntToStr(LInInteger);
if cboCommands.ItemIndex<>5 then begin
lbCommunication.Items.Insert(0,'We said -> ' + LCommand);
lbCommunication.Items.Insert(0,'Server said -> ' + LInString);
end ;
//вот здесь отправляется команда на получение массива
if cboCommands.ItemIndex=5 then begin
lbCommunication.Items.Insert(0,'We said -> ' + LCommand);
AssignFile(tfile,edit2.Text);
reset(tfile);
writeinteger(maslength);
setlength(sdp.DF,maslength);
setlength(pocket,maslength+12);
ReadBuffer(Pocket[0],length(Pocket));
SDP.n:=Getinteger(Pocket,0);
SDP.l:=Getinteger(Pocket,4);
SDP.crc_32:=Getinteger(Pocket,maslength+8);
for i:=8 to maslength+7 do
sdp.DF[i-8]:=pocket[i];
dzapis(maslength);
lbCommunication.Items.Insert(0,'server said -> Bufer prinyat' ) ;
lbCommunication.Items.Insert(0,'We said -> n = ' + inttostr(sdp.n));
lbCommunication.Items.Insert(0,'We said -> l = ' + inttostr(sdp.l));
lbCommunication.Items.Insert(0,'We said -> crc_32 = ' + inttostr(sdp.CRC_32));
crc_32:=$ffffffff;
crc_32:=crc32.CalculateCRC32(sdp.df,maslength );
lbCommunication.Items.Insert(0,'We said -> crc_32 = ' + inttostr(crc_32));
closefile(tfile);
end;