Posts: 3,671
Threads: 146
Joined: Jan 2011
Reputation:
119
01-31-2014, 18:19
(This post was last modified: 01-31-2014, 18:59 by Nekochan.)
Hey guys,
I am doing my custom networking for my engine, so I need a little help. I'm using UDP socket, but as you know ( maybe ): "udp sends a packet and you'll never know - will it reach the destination or not."
So I am trying to make some kinda of "packet data check".
Pseudocode:
I got the struct called 'svpackets', this struct contains "char header[4];", "int clientIndex"; and 'bool clientGotMessage;'
So when the server sends a message to the client, it also fills the struct like:
Code: svpackets[i].header[0] = CLIENT_MESSAGE_HEADER;
// using rand to prevent message bothering
svpackets[i].header[1] = 0x3f * ( _sv.time * rand() % 0x2f + 0x4f );
svpackets[i].header[2] ... etc
svpackets[i].clientgotmessage = false; // not yet
svpackets[i].clientIndex = client.Number; // parameter
net_sendpacket(my data blablabla with svpackets.header);
++i;
if(i > 30)
i = 0; .. etc
Server runs loop, which also checks every client with svpacket, if svpacket.clientgotmessage equals TRUE, so just 'continue;'; If svpacket.clientgotmessage = false; so run timer for ~10 seconds and kick the client ( just because no packets for a long time ).
Soo, when client got the message from a server with 'CLIENT_MESSAGE_HEADER' header, it sends THE SAME header, but only changes the 'header[0]' to another value, so server will know that it is "return message", where it will set "clientGotMessage" to true.
The same method I've used for a clientsystem;
Since I am working with networking not for so long time, I am not sure at all.
It works great now, but as I've said before, I am not sure that it's good system at all,
is there any tip to make it better?
Here's what I got now:
PHP Code: /*
process client requests ( not client connect requests )
*/
void sv_processclient( netdata_t from, char *header, const char *message, const char *advanced )
{
int i;
serverclient_t *p_temp;
char *c_header;
// ignore connectionless packets
if( sv_checkmagic( header, NET_OOB_BYTE1 ) )
return;
// ignore client requests
if( sv_checkmagic( header, CL_COMMAND_MAGIC ) && cl_running->integer)
return;
// ignore server commands
if( sv_checkmagic( header, SVCL_COMMAND_MAGIC1 ) )
return;
// find the client
p_temp = sv_getclientbyip( from.sockaddress );
if(!p_temp)
{
com_print("sv_processclient: couldn't find client by an ip address\n");
return;
}
// client must be connected! ( not even 'connecting' )
if(p_temp->state != SVCL_CONNECTED) // just an empty slot
return;
if(p_temp->type == NA_BOT) // we don't need to
return;
switch (header[0]) {
//
// css packet apply
//
case (char)SVCL_COMMAND_MAGIC5:
for( i = 0; i < MAX_COMMAND_SEQUENCE; i++ ) // using 'MAX_COMMAND_SEQUENCE' since _sv.cmdIndex could get reset at the same time, so loop thru every entry
{
if( (_sv.cmd_sequence[i].clientId == _sv.clients[p_temp->clientnum].clientnum) && _sv.cmd_sequence[i].used ) // check used css and owner of css
{
// MAGIC5 is a client identificator
if( ((char)_sv.cmd_sequence[i].encodedMsg[0] == (char)header[1] && // indentify by the header
(char)_sv.cmd_sequence[i].encodedMsg[1] == (char)header[2] &&
(char)_sv.cmd_sequence[i].encodedMsg[2] == (char)header[3] &&
(char)_sv.cmd_sequence[i].encodedMsg[3] == (char)header[4] ))
{
_sv.clients[p_temp->clientnum].lastCommandTime = _sv.time;
_sv.clients[p_temp->clientnum].commandIndex++;
_sv.cmd_sequence[i].index = 0;
_sv.cmd_sequence[i].recvtime = _sv.clients[p_temp->clientnum].lastCommandTime;
_sv.cmd_sequence[i].used = false;
// so we don't need it anymore for current client
//sv_resetsequence( _sv.cmd_sequence[i] );
//_sv.cmdIndex--;
}
}
}
return;
//
// client commands
//
case (char)CL_HEADER_MAGIC:
c_header = net_cmp4header( CL_COMMAND_MAGIC, header, 1 );
//
// client commands
//
/* client sent a message, send it to everyone */
if(!strcmp( message, "cl_say"))
{
sv_sendservercommand( NULL, "cl_chat \"%s\" \"%s\"", p_temp->name, advanced );
net_sendpacket( strlen(c_header), c_header, from );
return;
}
// we won't resend CSS just because we don't need it
if(!strcmp( message, "disconnect"))
{
com_print( "%s disconnected\n", p_temp->name );
sv_dropclient( p_temp->clientnum, advanced );
}
if(!strcmp( message, "cl_reconnect"))
{
// TODO
return;
}
return;
//
// unrecognized packets
//
default:
com_print("WARNING: unknown packet data from '%s'\n", p_temp->name);
sv_dropclient( p_temp->clientnum, "unknown data recieved\n" );
break;
}
}
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
Posts: 13
Threads: 9
Joined: Oct 2013
Reputation:
0
Wow now you we ask for help ) unfortunately I don't know
Posts: 284
Threads: 21
Joined: Jun 2012
Reputation:
13
Posts: 3,671
Threads: 146
Joined: Jan 2011
Reputation:
119
(02-01-2014, 19:24)Ich1994 Wrote: What about using TCP?
I don't want to use it because there are several reasons.
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
Posts: 284
Threads: 21
Joined: Jun 2012
Reputation:
13
(02-01-2014, 23:11)SailorMoon Wrote: (02-01-2014, 19:24)Ich1994 Wrote: What about using TCP?
I don't want to use it because there are several reasons.
Then list them doe....
Posts: 3,671
Threads: 146
Joined: Jan 2011
Reputation:
119
(02-02-2014, 00:37)Ich1994 Wrote: (02-01-2014, 23:11)SailorMoon Wrote: (02-01-2014, 19:24)Ich1994 Wrote: What about using TCP?
I don't want to use it because there are several reasons.
Then list them doe....
Well, this is not that important.
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
Posts: 284
Threads: 21
Joined: Jun 2012
Reputation:
13
(02-02-2014, 13:31)SailorMoon Wrote: (02-02-2014, 00:37)Ich1994 Wrote: (02-01-2014, 23:11)SailorMoon Wrote: (02-01-2014, 19:24)Ich1994 Wrote: What about using TCP?
I don't want to use it because there are several reasons.
Then list them doe....
Well, this is not that important.
Nice to know...
Posts: 165
Threads: 14
Joined: Jul 2011
Reputation:
8
02-05-2014, 19:50
(This post was last modified: 02-05-2014, 19:54 by narkos.)
Hello,
When i was creating a multiplayer game with XNA, i was using "lidgren network gen3" ( http://code.google.com/p/lidgren-network-gen3/) for the network part, it was very easy to use and worked very well, maybe you can take a look at the source to get some good points from it. If i'm not wrong, it uses a combination of UDP and TCP.
A bit of info:
There are five delivery methods available:
Unreliable This is just UDP. Messages can be lost or received more than once. Messages may not be received in the same order as they were sent.
UnreliableSequenced Using this delivery method messages can still be lost; but you're protected against duplicated messages. If a message arrives late; that is, if a message sent after this one has already been received - it will be dropped. This means you will never receive "older" data than what you already have received.
ReliableUnordered This delivery method ensures that every message sent will be eventually received. It does not however guarantee what order they will be received in; late messages may be delivered before newer ones.
ReliableSequenced This delivery method is similar to UnreliableSequenced; except that it guarantees that SOME messages will be received - if you only send one message - it will be received. If you sent two messages quickly, and they get reordered in transit, only the newest message will be received - but at least ONE of them will be received.
ReliableOrdered This delivery method guarantees that messages will always be received in the exact order they were sent.
Hope this help.
Posts: 3,671
Threads: 146
Joined: Jan 2011
Reputation:
119
(02-05-2014, 19:50)narkos Wrote: Hello,
When i was creating a multiplayer game with XNA, i was using "lidgren network gen3" (http://code.google.com/p/lidgren-network-gen3/) for the network part, it was very easy to use and worked very well, maybe you can take a look at the source to get some good points from it. If i'm not wrong, it uses a combination of UDP and TCP.
A bit of info:
There are five delivery methods available:
Unreliable This is just UDP. Messages can be lost or received more than once. Messages may not be received in the same order as they were sent.
UnreliableSequenced Using this delivery method messages can still be lost; but you're protected against duplicated messages. If a message arrives late; that is, if a message sent after this one has already been received - it will be dropped. This means you will never receive "older" data than what you already have received.
ReliableUnordered This delivery method ensures that every message sent will be eventually received. It does not however guarantee what order they will be received in; late messages may be delivered before newer ones.
ReliableSequenced This delivery method is similar to UnreliableSequenced; except that it guarantees that SOME messages will be received - if you only send one message - it will be received. If you sent two messages quickly, and they get reordered in transit, only the newest message will be received - but at least ONE of them will be received.
ReliableOrdered This delivery method guarantees that messages will always be received in the exact order they were sent.
Hope this help.
That's useful for me, thanks. Also I don't want to use 3rd party libs/apps, just because I want to earn some experience.
C++/Obj-Cdeveloper. Neko engine wip
Steam: Click
|