Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.01;
Скачать: CL | DM;

Вниз

присвоение данных из ф-ции   Найти похожие ветки 

 
Galiaf ©   (2006-09-08 15:52) [0]

Привет всем кто не спит… днём  =)!
Есть у меня переменная s: pchar если я присваиваю значение так: s:=’stroka’, то никаких проблем нет. Но если я присваиваю значение функции, в моем случае это NET_GetLocalIP(библиотека l-net XProger’a), то при попытке отправить s клиенту/серверу, неважно кому, просто отправить, то получается что я отправляю не то что мне вернула ф-ция а какую-то… непонятность хотя если я присваиваю s:=’stroka’, то приходит именно ‘stroka’. Думаю это связано с тем, что при присваивании значения ф-ции переменная получает адрес откуда эта функция брала данные и при попытке отправить их получающий видит не строку  а непонятности всякие которые находятся у НЕГО по этому адресу имхо. Вот мне теперь нужно узнать как присвоить переменной значение ф-ции так, чтобы можно было отправить и получить правильное значение. Сам я пробовал то, что приходило в голову но ничего не помогло, пробовал через указатель присваивать но мысль эта изначально неверна. Может у вас есть идея как это организовать, желательно что бы код был по-шустрее.


 
Elen ©   (2006-09-08 15:57) [1]


>  NET_GetLocalIP

Какой тип она возвращает?


 
Loginov Dmitry ©   (2006-09-08 16:00) [2]

Передаешь ставшие неактуальными данные.
Приведи код, как ты это делаешь.


 
Galiaf ©   (2006-09-08 19:41) [3]


> Elen ©   (08.09.06 15:57) [1]

pchar истествинна :)


> Loginov Dmitry ©   (08.09.06 16:00) [2]

pls[currentplayer].ip:=NET_Getlocalip;
или еще
while NET_Recv(@buf, 255, IP, Port, recv) > 0 do
 pls[countplayers].ip:=ip;

Здесь я записываю ip пришедшего пакета когда кто-либо подключается для того чтобы позже знать кому и по какому адресу отправлять пакеты, так же весь массив перед стартом игры отправляется клиентам для того что бы они могли писать другим игрокам. Т.о. сервак может всем отправлять пакеты а клиенты не могут т.к. пришедшие данные неправильны.
это если не писать ненужные здесь команды, суть не меняет. В переменную ip функция пишет с какого ip пришел пакет.

описывать ф-ции не буду, вот ссылка на библиотеку, весит килобайт 5:
http://xproger.mirgames.ru/files/lib/l_net.rar


 
Loginov Dmitry ©   (2006-09-08 19:53) [4]

> while NET_Recv(@buf, 255, IP, Port, recv) > 0 do


IP - это переменная типа PChar? Тогда тебе самостоятельно нужно выделять память под эту переменную.
Не помешало бы привести объявление функции NET_Recv.


 
Galiaf ©   (2006-09-08 20:42) [5]

и за чем я только ссылку давал...
ip: pchar; воооооооон там внизу написано :).

function NET_Recv(Buf: pointer; Count: integer; var IP: PChar; var Port: integer; var RecvBytes: integer): integer;
var
from    : sockaddr_in;
i       : integer;
UID     : DWORD;
s       : string;
begin
Result := 0;
if (not NET_Ready) or (NET_Socket <= 0) then Exit;
if (Count <= 0) or (Count > MaxBufLen) then Exit;
i := SizeOf(from);
Result := recvfrom(NET_Socket, NET_tmpBuf[0], Count, 0, from, i);
if Result <= 0 then
begin
Result    := -1;
RecvBytes := Result;
Exit;
end;

dec(Result);
if Result > 0 then
begin
IP   := inet_ntoa(from.sin_addr);
Port := ntohs(from.sin_port);

case NET_tmpBuf[0] of
// Пришёл обычный пакет
 0 : Move(NET_tmpBuf[1], PByteArray(buf)[0], Result);
// Пришёл отчёт о доставке
 1 : begin
     Move(NET_tmpBuf[1], UID, 2);
     s := StrPas(IP);
     for i := 0 to Length(NET_APLs) - 1 do
      if (NET_APLs[i].UID  = UID) and
         (NET_APLs[i].Port = Port) and
         (NET_APLs[i].IP   = s) then
       begin
       NET_APLs[i].trys := 255;
       break;
       end;
     // Рекурсия до тех пор, пока не получим пакет (0, 2)
     // или пока в стеке не закончатся данные
     Result := NET_Recv(Buf, Count, IP, Port, RecvBytes);
     end;
// Пришёл APL пакет
 2 : begin
     dec(Result, 2);

     Move(NET_tmpBuf[1], UID, 2);

     // Посылаем подтверждение об отправке
     NET_tmpBuf[0] := 1;
     i := SendTo(NET_Socket, NET_tmpBuf[0], 3, 0, from, SizeOf(from));

    // Контроль двойных APL пакетов
     for i := 0 to APLreglen - 1 do
      if (APLreg[i].UID = UID) and
         (APLreg[i].Port = Port) and
         (APLreg[i].IP = StrPas(IP)) then
       begin
       Result := NET_Recv(Buf, Count, IP, Port, RecvBytes);
       Exit;
       end;

     Move(NET_tmpBuf[3], PByteArray(Buf)[0], Result);

     APLreg[regseek].UID  := UID;
     APLreg[regseek].Port := Port;
     APLreg[regseek].IP   := StrPas(IP);
     inc(regseek);
     if regseek >= APLreglen then
      regseek := 0;
     end;
 end;
end;
RecvBytes := Result;
end;

На счет выделения памяти, как это сделать для переменной pchar? Еще у меня ведь запись которая содержит массив из записи содержащей переменную в которой хранить собираюсь ip, ща скопирую:

type
 tpls=record
   ip: pchar;
   name: string[15];
   model: byte
 end;

 tdat3=record
   pls: array[0..9] of tpls;
   count: byte;
 end;

var
 dat3: tdat3;//вото это я отсылаю клиентам перед стартом игры
 pls: array[0..9] of tpls;{а здесь я храню ip и клиенты при получении dat3 записывают сюда же}

не знаю надо ли но на всякий случай написал.
Я сперва беру ip и записываю в pls[i].ip а когда приходит время отправлять я отсюда беру и записываю в dat3.pls[i].ip и отправляю.
Я может быть и разобрался бы с этой проблемой но очень редко сейчас удается проверить игру на двух компах а без этого никак.


 
Rial ©   (2006-09-08 21:46) [6]

Для того, чтобы проверить работу сети нет необходимости в 2 компах.
Пожно лидо создать виртуальную сеть, либо просто
обмениваться данными в пределах одного компа.

IP:=StrAlloc(MaxByte); //выделение памяти
IP:=StrPCopy(OldIP);   //копирование адреса
...
StrDispose(IP);        //очистка памяти

P.S.
UID     : DWord;
замени на
UID     : Word;


 
Galiaf ©   (2006-09-08 23:25) [7]


> Rial ©   (08.09.06 21:46) [6]

ээээээээээ, создать виртуальную сеть??? возможно я что-то путаю но даже так если я посылаю не данные а адрес то получу правильные данные по этому адресу, т.е. не смогу понять что допустил ошибку да и проверка на одном компе у меня пока не удавалась, пакеты просто не доходят до второй программы, возможно они сразу удаляются после приема первой програмой.
И вообще что значит создать виртуальную сетьи главное как?


 
Rial ©   (2006-09-09 00:51) [8]

>если я посылаю не данные а адрес то получу
> правильные данные по этому адресу

Не понял сути.


> возможно они сразу удаляются после приема первой програмой

Глупость.

Я так понял, ты посылаешь личные сообщения, с указанием сокета и адреса.
Просто на одном компе, по идее, один сокет(порт) может быть открыт только
одним приложением одновременно. Поэтому если ты запускаешь
2 приложения, то второе просто не может принять данные, так как
не может получить доступ к сокету. Надо для второй копии
открывать другой доступный сокет, о чем грамотно информировать
предыдущую копию. Например, с помощью широковещательного сообщения.
Далее идет обмен по одному адресу, но разным сокетам.
Короче говоря, нужно много предусмотреть.

Но этот модуль сам по себе рабочий, если заменить ту строку, о которой
я уже упоминал. Поэтому за него можешь не волноваться.

Вообще, то, что ты отправляешь из одного приложения, должно доходить
и до него в том числе.

А про виртуальную сеть забудь. Не стоит в данном случае овчинка выделки.


 
Loginov Dmitry ©   (2006-09-09 09:19) [9]

> и за чем я только ссылку давал...
> ip: pchar; воооооооон там внизу написано :).


Классная ссылка. Прогу можно описать так: программа демонстрирует работу TMemo и TEdit. Но есть особые фичи: текст в Мемо нельзя редактировать! Во как.
Если ввести текст в TEdit и нажать Enter, то он будет удален!

Другой функциональности пока не замечал.

Замечательная прога :-)


 
Rial ©   (2006-09-09 12:53) [10]

> [9] Loginov Dmitry ©   (09.09.06 09:19)


:)))
Спасибо, утро прошло не зря.


 
Palladin ©   (2006-09-09 21:16) [11]

О чем эта ветка?


 
Galiaf ©   (2006-09-09 22:44) [12]


> Loginov Dmitry ©   (09.09.06 09:19) [9]

Ты поднял мне настроение этой речью... так легко... не думая даже. =)
а если подумать, да еще и посмотреть... огого! да там модуль некий подключен... l_net.pas, а в модуле-то и функция та самая лежит =)

А пример - это чат, который работает с сетью пользуя великолепный протокол(наверо так) UDP, а великолепен он многими особенностями которые я в игре очень хорошо решил пользовать. Да еще автор напрягся и сделал сей протокол еще удобнее... ано... о чем это я?


> Не понял сути.

я имею в виду, что по-моему при отправке сервером  в моем случае клиент(если можно так выразиться) получает не данные а адрес этих самых данных в памяти но так как данные находятся в памяти сервера, а не клиента, то клиент по этому адресу берет неправильные данные, а если запустить 2 игры на одной машине то выйдет что клиент хоть и получает адрес(а не данные) но по этому адресу видит те самые данные. т.о. я не смогу понять что отправляю неправильно. это конечно все имхо т.к. я человек крайне неуверенный в себе и даже очевидные вещи могут казаться мне возможно неверными.

Да и нет уже большой необходимости в двух компах т.к. основная работа с  сетью уже готова, осталось лишь разобраться с сабжом и вставить некоторые мелочи.


> > возможно они сразу удаляются после приема первой програмой
>
> Глупость.

думаю всеже это может быть правдой, в модуле автор писал:
"Count желательно указывать максимально большим, т.к. не прочитанные из пакета данные будут утеряны"
возможно я ошибаюсь но мне кажется, что он имел в виду что пакеты удаляются после приемя. Но это не значит что я считаю твое мнение неверным, наооборот, стоит прислушаться.

что-то в голову приходит мысль, в примере, по той самой ссылке который, используется широковещательное сообщение но если запустить две программы, дойдет только до первой, кажется так. Еще помню пробовал как-то на tcp делать, компонентами какими-то, давно было правда, так вроде небыло проблем с проверкой на одном компьютере...


 
Rial ©   (2006-09-09 23:09) [13]

1.
> "Count желательно указывать максимально большим, т.к. не
> прочитанные из пакета данные будут утеряны"

Вся проблема в том, что мы с тобой не понимаем друг друга.

После приема программой А пакета X в ее стеке пакетов
пакет удаляется. А программа А не может больше его никак получить.
Это так же, как и, например, с оконными сообщениями.
Но если был отправлен, например, широковещательный патек,
то, после того, как программа А получила пакет X, этот
патек остается в стеке пакетов для программы B. Поэтому
программе B нет никакой разницы, получила ли пакет программа А.

Вот моя мысль. В твоей я нашел противоположную. Если что не так, извини.

2.
> я имею в виду, что по-моему при отправке сервером  в моем
> случае клиент(если можно так выразиться) получает не данные
> а адрес этих самых данных в памяти но так как данные находятся
> в памяти сервера, а не клиента, то клиент по этому адресу
> берет неправильные данные, а если запустить 2 игры на одной
> машине то выйдет что клиент хоть и получает адрес(а не данные)
> но по этому адресу видит те самые данные.


Что то ты не так понимаешь.
При отправке Data : Array[0..255] of Byte; (образно выражаясь)
ты получишь именно те данные, которые ты отправлял.

При всем желании, в windows память у двух процессов разделена,
и по указателю их другого процесса в этом процессе
ты обратиться не можешь. Просто получишь AV.
Беда в том, что в этом модуле есть 2 бага, которые я
уже не смогу вспомнить. Если надо, могу дать исправленный
и переработанный модуль.
Хотя, возможно, не до конца исправленный ))


 
Galiaf ©   (2006-09-10 00:10) [14]


> Вся проблема в том, что мы с тобой не понимаем друг друга.

Ты имеешь в виду, что я тебя не понимаю или серьезно мы друг друга не понимаем? =)


> Вот моя мысль. В твоей я нашел противоположную. Если что
> не так, извини.

Я высказывал только то как я на текущий момент себе это представлял и твоя мысль у меня в башке тоже была но много глубже =) и соответственно я не осознавал этого.

Ты 2 раза написал патек :)

А что собственно в модуле не так, пока всё вполне утраивает? если можно дай, я посмотрю что ты там изменил может и правда что не так... ты бы еще автору сообщил...


> P.S.
> UID     : DWord;
> замени на
> UID     : Word;

вот еще не могу понять зачем оно нужно, вроде разници никакой, или я не в том направлянии думаю? конкретнее, конкретнее...

зы
только сейчас принялся проверять на практике вышеупомянутые идеи т.к. появился комп №2


 
Galiaf ©   (2006-09-10 01:05) [15]


> Rial ©   (08.09.06 21:46) [6]

как я понимаю тамошние строки должны были выделить память для переменной(IP) в которую хочу вписать данные(OldIP) и затем те данные записать, и как выбрасывают прогу место под переменную освободить... если так, ничего не изменилось :(
StrPCopy просит 2 параметра, строку я делал "" в смысле пустую, может там что-то особенное надо? в хэлпе нет ничего про эту строку, просо source и все тут. И вообще хэлп говорит, что это Copies an AnsiString to a null-terminated string, при чем тут это? зачем копировать string в pchar или я опять заблуждаюсь? путаюсь.
пробовал вместо stralloc strnew, но лучше от этого не стало.

меня начинают посещать страшные мысли: неужели всё так плохо, неужели мир так безнадёжен??? аааааааа, где мой набор для харакири??? если быть точнее я начинаю думать о том чтобы просто отправлять данные из stringgrid"a в который я паралельно записываю ip, или еще чего хуже, переводить каждый раз строку в набор цифр и отправлять в таком виде =)


 
Galiaf ©   (2006-09-10 01:33) [16]

вот я проверил

var
 str: string;
 ip: тот самый, из ф-ции
 add: pchar  в который я собираюсь сунуть и который позже отправить

str:=ip;
add:=pchar(str);

работает, но нет во мне желания пользовать сей метод


 
Rial ©   (2006-09-10 01:58) [17]

> Ты 2 раза написал патек :)

Как я рад, что ты заметил. Значит, я не зря распинался тут.

Т.к. строка у тебя находится во внешнем источнике,
тебе ее скопировать нужно. Это ясно.

> str:=ip;
> add:=pchar(str);

Кошмар. Причем работает до поры до времени, т.к.
нет гарантии, что add кончится нулем там, где нужно.


> вот еще не могу понять зачем оно нужно, вроде разници никакой,
> или я не в том направлянии думаю? конкретнее, конкретнее...

Не торопись.
Разница есть !
Dword - 4 байта.
Word - 2 байта.

>     Move(NET_tmpBuf[1], UID, 2);

Обрати внимание: копируются именно 2 байта.
А что, по-твоему лежит в оставшихся двух ?
Правильно - что угодно. Поэтому и нужно менять
Dword на Word.

А вот второй баг не помню ... долго искал ...

Это правда не умоляет заслуг XProger-а.
Ему отдельное спасибо.

StrAlloc и StrNew - в общем то, разные функции.
Это тебе не AllocMem и GetMem, у коих тоже правда
небольшое отличие имеется.

Если честно, я уже не разберусь в чем тут у нас проблема.
Запутался я. Что именно ты желаешь узнать, уточни ?

Вот пример рабочего исходника:

http://www.Rial578.narod.ru/protected/netsource.rar


 
Galiaf ©   (2006-09-10 13:04) [18]


> Если честно, я уже не разберусь в чем тут у нас проблема.
>
> Запутался я. Что именно ты желаешь узнать, уточни ?


Да всё та же, если я присваиваю данные из функции, то до клиента не дойдет, а если s:="strka" или как я еще писал

 str:=ip;
 add:=pchar(str);

то клиент получит то, что должен. Я хочу узнать как в переменную присвоить  более ровным способом данные чем тот способ который 2 строки выше.


> Rial ©   (08.09.06 21:46) [6]

у меня ничего не изменилось, но может во втором параметре StrPCopy, который там почему-то не указан, нужно писать что-то важное, я же писал
StrPCopy(oldIP,"")

за ссылку отдельное спасибо.



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

Текущий архив: 2006.10.01;
Скачать: CL | DM;

Наверх




Память: 0.55 MB
Время: 0.06 c
15-1157744465
Strate
2006-09-08 23:41
2006.10.01
Подскажите тест на профориентацию


2-1157997488
Adios
2006-09-11 21:58
2006.10.01
помогите разобраться


3-1153862992
Couter Terranist
2006-07-26 01:29
2006.10.01
Порекоммендуйте хорошее пособие по Oracle.


15-1157806975
new_user1
2006-09-09 17:02
2006.10.01
Как узнать...


15-1157911918
sportman
2006-09-10 22:11
2006.10.01
Сеть и почта!!!