Форум: "Начинающим";
Текущий архив: 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.011 c