Since UDP is packet-oriented, the data won''t be split. recv() returns exactly what you passed to send(). However, packets may receive out of order, or not at all.
TCP is stream-oriented, so the data may be split. recv() may return only a part of what was sent with send(), or it might return the data of more than one send() etc... However, the data will always be in order, and nothing will ever be dropped (unless the connection breaks of course).
cu,
Prefect
One line of sourcecode says more than a thousand words.
Efficient Packet Structures - Help?
I was ware that TCP send() would group together packets and than send them; however to my understanding in a TCP stream only one packet at a time should be returned into the buffer during a single recv() call, thus meaning that you have to make several recv() calls to receive the data, even though it has been sent in one send() call.
Is this right or wrong?
Gamedev''s AI Auto-Reply bot.
Is this right or wrong?
Gamedev''s AI Auto-Reply bot.
Gamedev's AI Auto-Reply bot.
That''s not correct. Using TCP, one send() can equal many recv()s, or many send()s can be received with a single recv(). There is no way to predict or assume how much will be received with each call. So your best bet is to assign some sort of buffer for the receiving side and have a receive function that calls recv(), adds that data to the buffer, then removes a single ''packet''(game packet, not network packet) from the buffer and returns it.
Well, as an attempt to not have to parse the strings from above, my other solution would be to create a structures for each type of outgoing packet, fill the structures, and read them back on the server end. The data is already sorted in the structure, however the problem that poses is... what structure am I supposed to be receiving? What happens if the packet is too large for the client?
I don''t think this is a good idea. The server and client computers might have different internal representations of ints, strings etc and it will mess up, unless you agree on representations beforehand.
I don''t think this is a good idea. The server and client computers might have different internal representations of ints, strings etc and it will mess up, unless you agree on representations beforehand.
Well, you could always add an encode() and decode() function to each structure that is responsible for converting to a specific byte order for network transport. The only thing you have to watch then is that you use a typedef for different platforms to make sure that ints are the same size etc...
But this is only a problem if you plan to run on multiple platforms. If your only target is windows then you don't have to worry about it.
Edited by - jonstelly on January 6, 2002 2:13:54 AM
But this is only a problem if you plan to run on multiple platforms. If your only target is windows then you don't have to worry about it.
Edited by - jonstelly on January 6, 2002 2:13:54 AM
I recommend doing three things (in order of importance):
1) Abstract the (de)serialization
2) Abstract the parsing
3) Abstract the transport mechanism
Abstracting the serialization means that the structures that describe packets are not the packets themselves. The structures that represent the data _should not_ be flat, however the serialization of them _must be.
Pluggable factories abstract the parsing, and only work well if the serialization is also abstracted.
The transport code shouldn''t care about the data, it should just deliver it however it''s told to deliver it (garuanteed, high priority, etc...).
Also keep in mind that IP6 is coming; consider hiding as much of the udp code that makes sense. Someday you may want to encrypt or compress the streamed data, or dip lower into the protocol stack and use raw ip packets (or even less) instead of udp ones.
The blobs are kept in a static MemoryPool, and are checked in and out; that way they can be kept checked out until the packet is processed and then reused. This elimanates the memory allocations/deallocations and reduces the copying.
1) Abstract the (de)serialization
2) Abstract the parsing
3) Abstract the transport mechanism
Abstracting the serialization means that the structures that describe packets are not the packets themselves. The structures that represent the data _should not_ be flat, however the serialization of them _must be.
Pluggable factories abstract the parsing, and only work well if the serialization is also abstracted.
The transport code shouldn''t care about the data, it should just deliver it however it''s told to deliver it (garuanteed, high priority, etc...).
Also keep in mind that IP6 is coming; consider hiding as much of the udp code that makes sense. Someday you may want to encrypt or compress the streamed data, or dip lower into the protocol stack and use raw ip packets (or even less) instead of udp ones.
struct Packet{u16 PacketID;u16 Length;};struct ChatPacket : public Packet{char* szChatter;};//I would put this inside my pluggable factory that handles chat packetsSerialize(Blob* pBlob, const ChatPacket& chatter){int l = strlen(chatter.szChatter);chatter.length = 4 + l;pBlob->Write(&chatter, 4); /*This writes the packetID and length words into the stream and advancese the stream pointer*/pBlob->Write(chatter.szChatter, l);}Deserialize(ChatPacket* pChatter, Blob* pBlob){pBlob->Read(pChatter, 4); /*Copies 4 bytes out of the stream, and advances the stream pointer*/pChatter.szChatter = &pBlob[0]; /*Points szChatter directly into the stream buffer. This avoids making bonus copies, however it also means that the blob must remain intact and unalterred until you''re done with the packet*/}
The blobs are kept in a static MemoryPool, and are checked in and out; that way they can be kept checked out until the packet is processed and then reused. This elimanates the memory allocations/deallocations and reduces the copying.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
You know, pure C really does rock sometimes. Have you seen the Quake engine code? It''s a real beauty (apart from the game.dll, that should''ve been C++). And serialization is abstracted through the use of Netchan_* functions.
cu,
Prefect
cu,
Prefect
Widelands - laid back, free software strategy
Yeah, I definatly like that methode you have there.
I just recently picked up my Game Developers magazine and was reading an article on pluggable factories.
Thanks for your suggestion, though I have a method in and working right now, I am not pleased with it, and will shortly try using plugable factories as a better solution to my problem.
Gamedev''s AI Auto-Reply bot.
I just recently picked up my Game Developers magazine and was reading an article on pluggable factories.
Thanks for your suggestion, though I have a method in and working right now, I am not pleased with it, and will shortly try using plugable factories as a better solution to my problem.
Gamedev''s AI Auto-Reply bot.
Gamedev's AI Auto-Reply bot.
Heres a crazy idea I''ve been kicking around in my head for a while. Why not treat each packet as a long bitstring. Some values, like angle, don''t need a whole short''s worth of precision. Save space by only using as many bits for each value as needed. You could then use bitwise operators to encode/decode the values into the bitstring. The disadvantage of this is that it''d probably require an intimate knowledge of the server and client OS''s internal representations for values.
You should be able to conciderably shrink the size of world update packets if, for every unit in the area, you can shrink the number of bits used to send the angles for unit orientation and possibly send limited precision delta values for position based on distance from the player.
-Daedalus
You should be able to conciderably shrink the size of world update packets if, for every unit in the area, you can shrink the number of bits used to send the angles for unit orientation and possibly send limited precision delta values for position based on distance from the player.
-Daedalus
DM's Rules:Rule #1: The DM is always right.Rule #2: If the DM is wrong, see rule #1.
All the data I am passing is stored in a holder that is of the needed precision... exactly.
That is not that far fetched of an idea, and would not require intimate knowledge of the OS, and a lot of people to my understanding employ this tactic when it is needed I assume.
This can also be worked into pluggable factories, just you would be required to pass the proper precision information, as well, and it would take a little more time to serialize and deserialize the data stream.
Gamedev''s AI Auto-Reply bot.
That is not that far fetched of an idea, and would not require intimate knowledge of the OS, and a lot of people to my understanding employ this tactic when it is needed I assume.
This can also be worked into pluggable factories, just you would be required to pass the proper precision information, as well, and it would take a little more time to serialize and deserialize the data stream.
Gamedev''s AI Auto-Reply bot.
Gamedev's AI Auto-Reply bot.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement