Networking Question
Re: Networking Question
mm ,pag tak iepriekš minēji ka viss kods jaapvieno kopā..
vai tad nevajadzēja būt tā..?
1. norādam pozīcijas
2. saspiežam tās vienā intā..//pos_pack
3.pos_pack sadalam bitos..//initBits()..storeBits untt
4.nosūtam..//chara ,izmerā..
vai tad nevajadzēja būt tā..?
1. norādam pozīcijas
2. saspiežam tās vienā intā..//pos_pack
3.pos_pack sadalam bitos..//initBits()..storeBits untt
4.nosūtam..//chara ,izmerā..
//OpenGL
Re: Networking Question
Tieši tā. Pareizi esi sapratis.
Re: Networking Question
nu bet tādā gadījumā sanāk sūtīt to lielo skaitli kuru viņš nemaz neļauj nosūtīt. Jo Izsūtāmo vai saņemamo failu max .. to neatļauj
Pēc shemas kā iepriekš rakstiju
+ kur tas ir minētsēts ka es tieši x,y,z definēju to +100-100 katrai vertibai?Limits +100 ir x, y un z mainīgajiem. Nevis pos_packet.
Pēc shemas kā iepriekš rakstiju
Code: Select all
int xi=(int)(x*10),yi=(int)(y*10),zi=(int)(z*10);
pos_packet_0 = xi | (yi << 10) | (zi << 20);
Paka0->write(pos_packet_0,-100.0f,+100.0f,0.01f,SPW_PK);//SPW_PK = GameMessageID -130
//OpenGL
Re: Networking Question
Nepareizi esi tu tur uzrakstījis kodu.
Vispirms vajag pakā pa bitiem sarakstīt individuāli to x/y/z (katram norādot kautvai savu min/max/prec). Paka uztur buferi, kuru tu vēlāk vari aizsūtīt pa soketu.
Reku biju rakstījis kas un kā: http://forums.gamedev.lv/viewtopic.php?p=1658#p1658
Saspiešana intā notiek writeFloat'ā + turpatās no tā int'u sadala pa bitiem un ieraksta iekšējā buferī. writeInt paņem tik cik tev bitus norāda. Manā piemērā piecus - tas dos iespēju nosūtīt max 32 id vērtības.
Vispirms vajag pakā pa bitiem sarakstīt individuāli to x/y/z (katram norādot kautvai savu min/max/prec). Paka uztur buferi, kuru tu vēlāk vari aizsūtīt pa soketu.
Reku biju rakstījis kas un kā: http://forums.gamedev.lv/viewtopic.php?p=1658#p1658
Code: Select all
Paka0->writeInt(SPW_PK, 5);
Paka0->writeFloat(x,-100.0f,+100.0f,0.01f);
Paka0->writeFloat(y,-100.0f,+100.0f,0.01f);
Paka0->writeFloat(z,-100.0f,+100.0f,0.01f);
socket->send(Paka0->getBuffer(), Paka0->getBufferSize());
Re: Networking Question
Njam., meiģināju izveidot tā kā teici bet velāk atsevišķi izsaucot "Send" komandu izmetas errors..
tā pat arī meiģināju uztaisīt. write3floats( ar 3 verībam)
vēlāk tās visas reizē izsūtot..
šādā veidā
jo es atsevišķi send funkciju nevarēju iegūt viņa vienkārši tad bija 0 vai tukš sūtijums
bet tad man problēmas radās šo te nolasīt..
meiģināju gan ar float gan void(x,y,z-100......)
izsaukt bet neizdevās..
sāku domāt.. varbūt izdarīt nedaudz savādāk
1.klientam pieslēdzoties nosūtīt tīrus 3 floatus //kā spawn poziciju (12baitu izmērā)
2. un tad
sūtīt saspiesto skaitli kuru iepriekš esmu apzīmējis
piem pie pozīcijām
0-stāvēt
1-iet pa dioganāli
2-uz augšu
3-uz leju
untt
un ~ iekļauties tajos -10 /+10
un iekš klienta rēķināt pārējo pozīcijas..
nedaudz arī palasīju RakNet pamācības..
nesaprotu to kā viņi var nosūtīt floatus struktūrā (lielos daudzumos neko nesaspiežot)
http://www.raknet.net/raknet/manual/bitstreams.html
tā pat arī meiģināju uztaisīt. write3floats( ar 3 verībam)
vēlāk tās visas reizē izsūtot..
šādā veidā
Code: Select all
bsOut.Write((RakNet::MessageID)GameMessageIDs);
bsOut.Write((char*)buffer_1,BBC_1);//x
bsOut.Write((char*)buffer_2,BBC_2);//y
bsOut.Write((char*)buffer_3,BBC_3);//z
peer->Send(&bsOut,HIGH_PRIORITY,RELIABLE_ORDERED,0,packet->systemAddress,false);
bet tad man problēmas radās šo te nolasīt..
meiģināju gan ar float gan void(x,y,z-100......)
izsaukt bet neizdevās..
sāku domāt.. varbūt izdarīt nedaudz savādāk
1.klientam pieslēdzoties nosūtīt tīrus 3 floatus //kā spawn poziciju (12baitu izmērā)
2. un tad
sūtīt saspiesto skaitli kuru iepriekš esmu apzīmējis
piem pie pozīcijām
0-stāvēt
1-iet pa dioganāli
2-uz augšu
3-uz leju
untt
un ~ iekļauties tajos -10 /+10
un iekš klienta rēķināt pārējo pozīcijas..
nedaudz arī palasīju RakNet pamācības..
nesaprotu to kā viņi var nosūtīt floatus struktūrā (lielos daudzumos neko nesaspiežot)
+unsigned char useTimeStamp; // Assign this to ID_TIMESTAMP
RakNet::Time timeStamp; // Put the system time in here returned by RakNet::GetTime()
unsigned char typeId; // This will be assigned to a type I've added after ID_USER_PACKET_ENUM, lets say ID_SET_TIMED_MINE
useTimeStamp = ID_TIMESTAMP;
timeStamp = RakNet::GetTime();
typeId=ID_SET_TIMED_MINE;
Bitstream myBitStream;
myBitStream.Write(useTimeStamp);
myBitStream.Write(timeStamp);
myBitStream.Write(typeId);
// Assume we have a Mine* mine object
// If the mine is at 0,0,0, use 1 bit to represent this
if (mine->GetPosition().x==0.0f && mine->GetPosition().y==0.0f && mine->GetPosition().z==0.0f)
{
myBitStream.Write(true);
}
else
{
myBitStream.Write(false);
myBitStream.Write(mine->GetPosition().x);
myBitStream.Write(mine->GetPosition().y);
myBitStream.Write(mine->GetPosition().z);
}
myBitStream.Write(mine->GetNetworkID()); // In the struct this is NetworkID networkId
myBitStream.Write(mine->GetOwner()); // In the struct this is SystemAddress systemAddress
This can potentially save us sending 3 floats over the network, at the cost of 1 bit.
Code: Select all
You can also write bits. Most of the time you will not care about this.
//OpenGL
Re: Networking Question
Nesaprotu tavu kodu. Kas tev tur par tik daudz buferiem? Vienu tikai vajag.
Reku tev gatavs un strādājošs kods ar visu lietošanas piemēru. Kļūdu gadījumus, protams, neapstrādāju, un tā vietā lietoju assert. Tavā ziņā ir tas, kā to labot, ja vajadzīgs. Ar optimizāciju arī neaizrāvos, uzsvars uz koda saprotamību.
Ļoti precīzi saglabā, aizsūta un izdrukā tavu id un x/y/z skaitļus 5 baitos (izmēru atgriež getBufferSize() metode).
RakNet'a koda gabalā tiek ietaupīts uz to, ka ja visas trīs pozīcijas x/y/z komponentes ir 0, tad tas tiek aizsūtīts īsāk. Nav diezko laba "optimizācija".
Reku tev gatavs un strādājošs kods ar visu lietošanas piemēru. Kļūdu gadījumus, protams, neapstrādāju, un tā vietā lietoju assert. Tavā ziņā ir tas, kā to labot, ja vajadzīgs. Ar optimizāciju arī neaizrāvos, uzsvars uz koda saprotamību.
Code: Select all
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdio.h>
class BitBuffer
{
public:
BitBuffer()
{
reset();
}
void reset()
{
pos = 0;
maxPos = 8*MAX_BYTE_COUNT;
memset(buf, 0, sizeof(buf));
}
void assign(const unsigned char* bytes, int byteCount)
{
assert(byteCount <= MAX_BYTE_COUNT);
pos = 0;
maxPos = byteCount * 8;
memcpy(buf, bytes, byteCount);
}
void writeInt(unsigned int x, int bits)
{
assert(bits <= 32);
assert(x < (1U<<bits));
for (int i=0; i<bits; i++)
{
putBit((x >> i) & 1);
}
}
void writeFloat(float x, float min, float max, float prec)
{
assert(x >= min && x <= max);
int bits = (int)ceilf(logf((max - min) / prec) / logf(2.0f));
writeInt((unsigned int)(0.5f + (x - min) / prec), bits);
}
unsigned int readInt(int bits)
{
assert(bits <= 32);
unsigned int x = 0;
for (int i=0; i<bits; i++)
{
x |= getBit() << i;
}
return x;
}
float readFloat(float min, float max, float prec)
{
int bits = (int)ceilf(logf((max - min) / prec) / logf(2.0f));
return min + readInt(bits) * prec;
}
const unsigned char* getBuffer() const
{
return buf;
}
unsigned int getBufferSize() const
{
return (pos+7)/8;
}
private:
void putBit(int bit)
{
buf[pos/8] |= bit << (pos%8);
pos++;
assert(pos < maxPos);
}
int getBit()
{
assert(pos < maxPos);
int bit = buf[pos/8] >> (pos%8);
pos++;
return bit & 1;
}
static const int MAX_BYTE_COUNT = 128; // max 1024 bits
unsigned char buf[MAX_BYTE_COUNT];
int pos;
int maxPos;
};
int main()
{
BitBuffer packet2;
{
int id = 12;
float x = 1.0f;
float y = -55.5f;
float z = 77.0f;
BitBuffer packet;
packet.writeInt(id, 4); // id = [0..15]
packet.writeFloat(x, -100.0f, +100.0f, 0.1f);
packet.writeFloat(y, -100.0f, +100.0f, 0.1f);
packet.writeFloat(z, -100.0f, +100.0f, 0.1f);
// te suuti otrai pusei
//socket->write(buf1.getBuffer(), buf1.getBufferSize());
// otraa puse sanjem un ieraksti buferii
packet2.assign(packet.getBuffer(), packet.getBufferSize());
}
int id;
float x, y, z;
id = packet2.readInt(4);
x = packet2.readFloat(-100.0f, +100.0f, 0.1f);
y = packet2.readFloat(-100.0f, +100.0f, 0.1f);
z = packet2.readFloat(-100.0f, +100.0f, 0.1f);
printf("%i %.1f %.1f %.1f\n", id, x, y, z);
}
RakNet'a koda gabalā tiek ietaupīts uz to, ka ja visas trīs pozīcijas x/y/z komponentes ir 0, tad tas tiek aizsūtīts īsāk. Nav diezko laba "optimizācija".
Re: Networking Question
es jau teicu ka mēģināju.. to ka iespējamo varinatu ,tāpēc tur bija tik daudz bufferu.. Jo kodu taisiju pec tada principa kā
-> sūtīt 1ienu //apvienoto intu vērtību..
un neko vairāk.. tikai vienai vertibai
hmh.. īsti nesapratu izsūtīšanas vietu..
tur kur ir tas buf1.getBuf..
// te suuti otrai pusei
//socket->write(buf1.getBuffer(), buf1.getBufferSize());
// otraa puse sanjem un ieraksti buferii
packet2.assign(packet.getBuffer(), packet.getBufferSize());
Tas ir kautkāds random buferis(chars) vai vienkārši..klases pārstāvis
jo sūtot Paku kā tādu, otrā pusē neko nesaņemu..
parbaudīju savienojumu..parastās komandas strādā (//bsOut.Write(..kkads floats), bet tad kad velos nosutit paku
klienta puse x,y,z=-100. ... ... ..
-> sūtīt 1ienu //apvienoto intu vērtību..
un neko vairāk.. tikai vienai vertibai
hmh.. īsti nesapratu izsūtīšanas vietu..
tur kur ir tas buf1.getBuf..
// te suuti otrai pusei
//socket->write(buf1.getBuffer(), buf1.getBufferSize());
// otraa puse sanjem un ieraksti buferii
packet2.assign(packet.getBuffer(), packet.getBufferSize());
Tas ir kautkāds random buferis(chars) vai vienkārši..klases pārstāvis
jo sūtot Paku kā tādu, otrā pusē neko nesaņemu..
parbaudīju savienojumu..parastās komandas strādā (//bsOut.Write(..kkads floats), bet tad kad velos nosutit paku
klienta puse x,y,z=-100. ... ... ..
//OpenGL
Re: Networking Question
Es nesaprotu, ko tu nesaproti.
Tev ir socket klase kautkāda ar vismaz šādu funkcionalitāti, pareizi?
Tad nu sūtīšanas vietā raksti:
Saņemšanas vietā raksti:
Kas te ir nesaprotams?
Tev ir socket klase kautkāda ar vismaz šādu funkcionalitāti, pareizi?
Code: Select all
class Socket {
// aizsūta no buffer bufera size baitus
void Write(const unsigned char* buffer, unsigned int size);
// mēģina nolasīt maxSize baitus buferī, un atgriež nolasīto baitu skaitu
int Read(unsigned char* buffer, unsigned int maxSize);
}
Code: Select all
BitBuffer buf;
buf.writeInt(id, 5);
buf.writeFloat(x, ...);
socket->Write(buf.getBuffer(), buf.getBufferSize());
Code: Select all
unsigned char temp[100]; // cik nu tev tur max baiti atnāk no tīkla
int size = socket->Read(temp, sizeof(temp));
BitBuffer buf;
buf.assign(temp, size);
id = buf.readInt(5);
x = buf.readFloat(...);
Re: Networking Question
hmh viss strada labi
vienīgi nolasot
ja izmantoju
tad visas vertibas nemaz chara netiek ierakstītas..
ja izsaucu
tad iegūstu pie izmēra 4 kas itkā ir par maz jo salīdzināju saņemtos čarus un pēdējā vērtība atšķīrās
tāpēc izdomāju to pieskaitīt klāt..
tad viss nosūtījās.. bet es nēsmu pārliecināts vai tā drīkstēja darīt..
+ pirmstam kodā redzēju to ka ar bitiem apzīmē inta izmēru ..to ierobežojot
vienīgi nolasot
ja izmantoju
Code: Select all
bsIn.Read((char*)temp,sizeof(temp));
ja izsaucu
Code: Select all
bsIn.Read((char*)temp,sizeof((char*)temp));
vietā saņēmuchar temp([0]76'L' | [1]126'~' | [2]189'1/2'[3]55'Q')
vēlāk nosverot sapratu ka trūkst 1 b..char temp([0]76'L' | [1]126'~' | [2]189'1/2'[3]81'Q')
tāpēc izdomāju to pieskaitīt klāt..
Code: Select all
bsIn.Read((char*)temp,sizeof((char*)temp)+1);
+ pirmstam kodā redzēju to ka ar bitiem apzīmē inta izmēru ..to ierobežojot
nevari ludzu pateikt pēc kā es varu aprēķināt to cik daudz intus es iegūšu pēc attiecīgā izmēra..?packet.writeInt(id, 4); // id = [0..15]
//OpenGL
Re: Networking Question
Paskaties, ko sizeof dara, un ko tas nozīmē, pirms lietot savu kodu, kuru tu, kā izskatās randomā raksti... Kamon, sizeof((char*)temp) ???
Vai tagad saproti atšķirību, starp "char c", "char* c", un "char c[100]" ?
Code: Select all
#include <stdio.h>
int main()
{
char c;
char* buf;
char big[100];
printf("%i\n", sizeof(c));
printf("%i\n", sizeof(buf));
printf("%i\n", sizeof(big));
}
Kas ir "cik daudz", un kas ir "pēc attiecīgā izmēra"? Cik daudz no kurienes? Kas ir tas ko tu skaiti? Kādus intus? Kas par izmēru?nevari ludzu pateikt pēc kā es varu aprēķināt to cik daudz intus es iegūšu pēc attiecīgā izmēra..?