Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по TCP/IP а может я вообще ничего не понимаю. [D5, Win95/98]


Страницы:   1 2

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 тут ни с какого боку не при чем.
Работа с указателями и динамически выделенной памятью.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо