Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2006.10.01;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.53 MB
Время: 0.012 c
4-1148823766
ффф
2006-05-28 17:42
2006.10.01
виртуальный com порт


6-1139698111
msdn11
2006-02-12 01:48
2006.10.01
AT+CMGS sms не уходит


2-1158011922
AndrejG
2006-09-12 01:58
2006.10.01
Как подключить DLL к проекту?


15-1158011449
Ньюби
2006-09-12 01:50
2006.10.01
Программы автоматического поиска ошибок в коде ?


2-1157960470
SFproG
2006-09-11 11:41
2006.10.01
Управление сайтом на Delphi





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский