Data Packets

Started by
21 comments, last by hplus0603 14 years, 11 months ago
I am now working on sending Data with TCP/IP but I am still really new to Winsock2 so I need a little bit of information... It's hard to find any information on sending Data Packets with C++ in Winsock2 so here is my question I want to send two packets for commands(like: Accept, Refuse, VersionWrong, VersionRight, ChatMsg, AdminMsg, ServerMsg) basicly I want to send each command packet twice one packet is the buffer size then the other is the answer..but I am really unclear how this works.. I've been finding stuff like this:
char *sendbuf = "this is a test";
char recvbuf = [DEFAULT_BUFFER];
int recvbufflen = DEFAULT_BUFFER;
so what I need help with is how to send this data properly and accuratly. Or a link to a website that might help me, I've tried Bejee's but I get confused with his code, due to the fact it's not Wi32 it's Unix or what ever it is xD so thanks in advanced
Advertisement
The Forum FAQ already answers this. You call send() on the integer value (preferably translated to network byte order), then you call send() on the actual data. If you worry about packet overhead and have turned off Nagling, then you want to send both at the same time, typically using WSASend() (or, under UNIX, writev()).

When receiving, you first receive the size of the length integer, translate it to host byte order, and then enter a loop that receives that many bytes (making sure that the indicated number of bytes isn't bigger than available buffer space).
enum Bool { True, False, FileNotFound };
Ok, so instead of sending a string like "Account Accepted" can I number my packets like this..

#DEFINE PACKET_ACCEPT 1#DEFINE PACKET_REJECT 2/** etc etc **/


so when I send a accept or reject I send 1 or 2?
You could, but if you ever wanted to change the numbering system, you would be in for a world of hurt.

I'd recommend simply using an enum so you can easily change numbering of sections of packet types with minimal efforts in case you need to cross that bridge in the future.
Care to explain?
Quote:Original post by ARC inc
Care to explain?


Let's say you have 1000 packets defined as:

#define PACKET_TYPE_1 1
...
#define PACKET_TYPE_1000 1000

Let's say cheaters map out all those opcodes and release a cheat that is hardcoded to those values. To break those cheats, you want to change all of the opcode values. Lots of fun, right?

If instead you used an enum, you'd have
enum Packet_Type
{
Type1 = 0,
...
Type1000
};
and a way easier job of changing the opcode values without much work as you can arbitrarily change certain ranges of opcodes by using the rules of enums. For example:
enum Packet_Type
{
Type1 = 10,
...
Type20 = 150
...
Type30 = 20
...
Type1000
};

Hope that helps.
I just number them. I've never liked the C++ enum. I use a class for each of the ServerEvents and ClientEvents so I can just access them like ServerEvents::PING and such. Simple.
#pragma onceclass ServerEvents{public:	const static unsigned short ENTITY_UPDATES = 1;	const static unsigned short REMOVE_PLAYER  = 2;	const static unsigned short UPDATE_BOUNDARIES = 3;	const static unsigned short PING = 4;};

I also use a binary buffer for writing messages. I should rewrite this article, but it will do:
Old article on packet formatting
I've used it for a few projects and it works really well.

Also make your server authoritative.
Thanks all for the help I'll take all your opinion's into thought :D
Ok, so new question!

I am wanting to make threads in my Server Architect so I can accept more then just a single connection..

After reading MSDN on Winsock2 it says something about SOMAXCON...Does that mean I need to change that into how many connections it waits for? or do I do something else...please help!!!

here is my listen code..

if(listen(ListenSocket, SOMAXCONN) == SOCKET_ERROR) {    printf("Listen Failed: %ld\n", WSAGetLastError());    closesocket(ListenSocket);    WSACleanup();    return 1;}


thanks in advanced once again :D
No, the SOMAXCON is just for the backlog of pending connections. For a one thread per socket approach you just need to pass each socket you create via accept() into the thread you've made for it, and you're done.

Note however that you do not need to have multiple threads to handle more than one socket. The typical way is to use select() on a collection of sockets (often including your listening socket) to tell you which ones are ready to give you data at a given point.

This topic is closed to new replies.

Advertisement