![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по TCP/IP а может я вообще ничего не понимаю. [D5, Win95/98]
arhis © (2004-02-04 12:58:00)В общем или я не догоняю чего-то в основах или не вижу элементарного.
Сервер посылает через сокет данные (1 байт: команда, 2-5 байт размер пакета без первых пяти, дальше идет дин массив из string[50]):
var command : byte;
p : ^LongInt;
buf :array of string[50];
под buf уже взяли из кучи и записали туда данные.
lenn - количесвто элементов массива.
Command:=3;
MySize:=(lenn)*51;
GetMem(buffer,5+MySize);
pBytearray(buffer)^[0]:=3;
p:=pointer(integer(buffer)+1);
p^:=MySize;
GetMem(pBuf,MySize);
pBuf^:=buf;
move(pBuf^,pointer(integer(buffer)+5)^,mySize);
freemem(pBuf,MySize);
label1.Caption:=IntToStr(Socket.SendBuf(buffer^,5+MySize));
Клиент из первого пакета берет команду читает размер и начинает прием:
ONREAD
var
bufferg : pointer;
resbuf : pointer;
rbuffer : TMemoryStream;
fff : array of string[50];
под поток из кучи взяли при инициализации программы, MylocalSize,bufsize,receiving глобальная переменная.
firstpacket:=false;
BlockSize:=Socket.ReceiveLength;
Getmem(bufferg,BlockSize);
Socket.Receivebuf(bufferg^,BlockSize);
if not(Receiving) then
begin
command:=pByteArray(bufferg)^[0];
if Command = 3 then
begin
BufSize:=pLongInt(integer(bufferg)+1)^;
MyLocalSize:=BlockSize-5;
Receiving:=true;
firstPacket:=true;
rbuffer.Clear;
rBuffer.SetSize(BufSize);
rBuffer.position:=0;
rBuffer.write(pointer(integer(bufferg)+5)^,BlockSize-5);
end;
if not(firstpacket) then
begin
MyLocalSize:=MyLocalSize+BlockSize;
rBuffer.write(bufferg^,BlockSize);
end;
if MyLocalSize=BufSize then
begin
met:=MyLocalSize div 51;
SetLength(resBuf,met);
Receiving:=false;
getmem(fff,bufSize);
rBuffer.position:=0;
rBuffer.read(fff^,BufSize);
move(fff^,pointer(resbuf)^,BufSize);
end;
freemem(bufferg,blockSize);
Команду и размер считываем правильно.
получаем ровно столько байт сколько послали.
вместо массива мусор.
Digitman (2004-02-04 15:51:00) [21]
> arhis
ты по-русски понимаешь ?
тебе ясным русским языком сказали - внутренняя организация дин.массивов отличаетсяот внутр.организации стат.массивов ! дин.массивы всегда предваряет заголовок, описывающий данные ! и его размер ненулевой ! где и как ты учитываешь это в своем коде ? нет этого !
поэтому я тебе и сказал - раз намек не пониял и не углубился в изучение внутр.структуры своего дин.массива, бросай эту затею и меняй дин.массив на TStringList, работа с ним ничуть не хуже чем дин.массив строк, зато гораздо наглядней, удобней и изящней
arhis (2004-02-04 15:45:00) [22]Ну и как я буду резервировать место в статическом массиве под элементы, когда в одном запросе их может быть 100 а в другом 10000000000000.
arhis (2004-02-04 15:14:00) [23]Да какая разница мувил я это или нет. Так я проверял что посылаю и посылал то что надо, а на приеме какаято фигня.
Verg (2004-02-04 14:55:00) [24]
> getMem(point,Mysize);
> move((Pointer(integer(buffer)+5)^),point^,MySize);
> for met:=1 to 5 do
> StringGrid1.cells[0,met]:=arrStr(point^)[met-1];
type ArrStr = array[0..1] of string[50];
PArrStr = ^ArrStr;
var
Point : PArrStr;
buffer : pointer;
begin
Point := PArrStr(pchar(buffer)+5);// И ВСЕ!! И не надо никуда ничего мувить! И не надо никаких тут динамических массивов!!!
for met := 0 to (MySize div sizeof(Pointer^[0])) - 1 do
StringGrid1.cells[0,met+1] := point^[met];
........................
..................
Verg (2004-02-04 14:45:00) [25]Ты, видимо вообще не понимаешь, что динамический массив - это не просто кусок памяти размером таким-то.
Аналогия здесь есть, но только частичная.
Ты неправильно работаешь не с массивами, ты неправильно работаешь с динамическимимассивами.
> type arrStr = array of String[50];
и
> type arrStr = array[0..1] of String[50];
Есть разница?!
Динамические массивы ближе всего к дельфозным Huge String или просто String.
Видишь разницу между var S : string; и S: string[20] ?
arhis (2004-02-04 14:19:00) [26]Подскажите где. я неправильно оращаюсь к массиву.
В передатчике после всего есть вот такой простой проверочный код и он прекрасно работает:
type arrStr = array of String[50];
point : pointer;
послали буфер;
label1.Caption:=IntToStr(Socket.SendBuf(buffer^,5+MySize));
берем указатель от балды
getMem(point,Mysize);
move((Pointer(integer(buffer)+5)^),point^,MySize);
for met:=1 to 5 do
StringGrid1.cells[0,met]:=arrStr(point^)[met-1];
Digitman (2004-02-04 14:14:00) [27]
> arhis (04.02.04 14:10) [11]
> вот это определение размера массива
> lenn - количнсвто элементов массива.
>
> MySize:=(lenn)*51;
ну неправильно это ! в корне неправильно...
неправильно именно твое предположение (основанное бог знает на чем), что твой дин.массив в памяти занимает lenn*51 байт
поэтому, чтобы не вдаваться в подробности организации дин.массивов, убирай его из программы и меняй на TStringList
arhis (2004-02-04 14:14:00) [28]Вся фигня с указателями из-за того, что мне этот стринг нафиг не нужен это мне ничего другого не придумалось, потом там будет дин массив из записи структуру которой я еще не определил, просто в ней не будет динамических элементов, поэтому я решил для начала в тупую послать массив из String[50].
arhis (2004-02-04 14:10:00) [29]вот это определение размера массива
lenn - количнсвто элементов массива.
MySize:=(lenn)*51;
Digitman (2004-02-04 14:10:00) [30]
> Verg © (04.02.04 14:05) [10]
угу... понаворочено там много чего
асинхронный + попытка обращения к дин.массиву как к статическому = вполне ожидаемый результат
Verg (2004-02-04 14:05:00) [31]Хотя что-либо вообще трудно понять в том "месиве" из всяческих поинторов, но по-моему, у него сокет асинхронный. А вообще, черт знает что...
Verg (2004-02-04 13:59:00) [32]var Rcvd, RecOnce : integer;
P : pchar;
begin
Rcvd := 0;
P := @Prefix;
while Rcvd < sizeof(Prefix) do
begin
RecOnce := Socket.ReceiveBuf((P+Rcvd)^, SizeOf(Prefix)-Rcvd);
if RecOnce <=0 then
Exit; // ERROR !!!
inc( Rcvd, RecOnce );
end;
Rcvd := 0;
SetLength(Param, Prefix.ParamSize);
P := @Param[1];
While Rcvd < Prefix.ParamSize do
begin
RecOnce := Socket.ReceiveBuf((P+Rcvd)^, Prefix.ParamSize - Rcvd);
if RecOnce <=0 then
Exit; // ERROR !!!
inc( Rcvd, RecOnce );
end;
List.Text := Param;
Digitman (2004-02-04 13:51:00) [33]
> беру массив переношу его содержимое
я не вижу в твоем коде определения фактического размера данных, занимаемых дин.массивом
Digitman (2004-02-04 13:49:00) [34]и к чему такие сложности вообще ?
объяви тип
TPrefix = packed record
Cmd: Byte;
ParamSize: Integer;
end;
замени array of string[] на TStringList
теперь передавай (предполагается блок.режим):
var
Prefix: TPrefix;
List: TStrings;
Param: String;
..
Prefix.Cmd := 3;
Param := List.Text;
Prefix.ParamSize := Length(Param);
Socket.SendBuf(Prefix, SizeOf(Prefix));
Socket.SendBuf(Param[1], Length(Param));
и принимай (предполагается блок.режим):
var
Command: Byte;
Prefix: TPrefix;
List: TStrings;
Param: String;
..
Socket.ReceiveBuf(Prefix, SizeOf(Prefix));
Command := Prefix.Cmd;
SetLength(Param, Prefix.ParamSize);
Socket.ReceiveBuf(Param[1], Length(Param));
List.Text := Param;
все ! и никаких сомнительных выкрутасов с указателями, явной работой с кучей, дин.массивами и пр.
Arhis (2004-02-04 13:38:00) [35]Объясните мне пожалуйста в чем я не прав.
Я беру массив переношу его содержимоев нетипизированный буфер, и этот буфер посылаю. Какая разница для протокола какие байты пересылать.
Digitman (2004-02-04 13:33:00) [36]
> дальше бог знает что
потому что передаешь черт те что, ибо динамический массив пытаешься передать/принять как статический
arhis (2004-02-04 13:14:00) [37]Размер первого пакета у меня всегда больше чем 5+51 байт, насколько я понимаю пакеты по TCPIP не могут обгонять друг друга. Читаем первый пакет: первый байт все в порядке комманда под номером три, 2-5 байты все в порядке размер массива в байтах в моем случае 40596, дальше бог знает что.
Reindeer Moss Eater (2004-02-04 13:10:00) [38]Проблема в том, что если посмотреть что пришло в первом 51 байте первого пакета после заголовка, то это совсем не напоминает то, что я туда записал.
Ты проверяешь не то, что пришло, а то, что ты что-то записал куда-то.
Это не обязательно то, что "пришло"
arhis (2004-02-04 13:08:00) [39]Проблема в том, что если посмотреть что пришло в первом 51 байте первого пакета после заголовка, то это совсем не напоминает то, что я туда записал.
Для того чтобы проверить что я посылаю я при передаче извлекаю тот самый массив из общего буфера посланных данных и он прекрасно читается.
Reindeer Moss Eater (2004-02-04 13:02:00) [40]TCP тут ни с какого боку не при чем.
Работа с указателями и динамически выделенной памятью.