fixed a lot of network troubles

This commit is contained in:
Magnus Auvinen 2008-10-19 09:10:55 +00:00
parent 1a28f88e72
commit 119b5af3d3
5 changed files with 58 additions and 56 deletions

View file

@ -317,9 +317,9 @@ int client_send_msg()
packet.data_size = info->size; packet.data_size = info->size;
if(info->flags&MSGFLAG_VITAL) if(info->flags&MSGFLAG_VITAL)
packet.flags = NETSENDFLAG_VITAL; packet.flags |= NETSENDFLAG_VITAL;
if(info->flags&MSGFLAG_FLUSH) if(info->flags&MSGFLAG_FLUSH)
packet.flags = NETSENDFLAG_FLUSH; packet.flags |= NETSENDFLAG_FLUSH;
if(info->flags&MSGFLAG_RECORD) if(info->flags&MSGFLAG_RECORD)
{ {
@ -398,8 +398,6 @@ void client_direct_input(int *input, int size)
msg_pack_end(); msg_pack_end();
client_send_msg(); client_send_msg();
dbg_msg("client", "sent direct input");
} }
@ -1675,7 +1673,7 @@ static void client_run()
if(reporttime < time_get()) if(reporttime < time_get())
{ {
if(config.debug) if(0 && config.debug)
{ {
dbg_msg("client/report", "fps=%.02f (%.02f %.02f) netstate=%d", dbg_msg("client/report", "fps=%.02f (%.02f %.02f) netstate=%d",
frames/(float)(reportinterval/time_freq()), frames/(float)(reportinterval/time_freq()),
@ -1843,7 +1841,6 @@ int main(int argc, char **argv)
dbg_msg("client", "starting..."); dbg_msg("client", "starting...");
engine_init("Teeworlds"); engine_init("Teeworlds");
/* register all console commands */ /* register all console commands */
client_register_commands(); client_register_commands();
modc_console_init(); modc_console_init();

View file

@ -73,8 +73,11 @@ int conn_flush(NETCONNECTION *conn)
if(!num_chunks && !conn->construct.flags) if(!num_chunks && !conn->construct.flags)
return 0; return 0;
/* send of the packets */
conn->construct.ack = conn->ack; conn->construct.ack = conn->ack;
send_packet(conn->socket, &conn->peeraddr, &conn->construct); send_packet(conn->socket, &conn->peeraddr, &conn->construct);
/* update send times */
conn->last_send_time = time_get(); conn->last_send_time = time_get();
/* clear construct so we can start building a new package */ /* clear construct so we can start building a new package */
@ -85,6 +88,7 @@ int conn_flush(NETCONNECTION *conn)
void conn_queue_chunk(NETCONNECTION *conn, int flags, int data_size, const void *data) void conn_queue_chunk(NETCONNECTION *conn, int flags, int data_size, const void *data)
{ {
unsigned char *chunk_data; unsigned char *chunk_data;
/* check if we have space for it, if not, flush the connection */ /* check if we have space for it, if not, flush the connection */
if(conn->construct.data_size + data_size + NET_MAX_CHUNKHEADERSIZE > sizeof(conn->construct.chunk_data)) if(conn->construct.data_size + data_size + NET_MAX_CHUNKHEADERSIZE > sizeof(conn->construct.chunk_data))
conn_flush(conn); conn_flush(conn);
@ -115,6 +119,7 @@ void conn_queue_chunk(NETCONNECTION *conn, int flags, int data_size, const void
resend->data_size = data_size; resend->data_size = data_size;
resend->data = (unsigned char *)(resend+1); resend->data = (unsigned char *)(resend+1);
resend->first_send_time = time_get(); resend->first_send_time = time_get();
resend->last_send_time = resend->first_send_time;
mem_copy(resend->data, data, data_size); mem_copy(resend->data, data, data_size);
} }
else else
@ -140,6 +145,12 @@ static void conn_send_control(NETCONNECTION *conn, int controlmsg, const void *e
conn->last_send_time = time_get(); conn->last_send_time = time_get();
} }
static void conn_resend_chunk(NETCONNECTION *conn, NETCHUNKDATA *resend)
{
conn_queue_chunk(conn, resend->flags|NET_CHUNKFLAG_RESEND, resend->data_size, resend->data);
resend->last_send_time = time_get();
}
static void conn_resend(NETCONNECTION *conn) static void conn_resend(NETCONNECTION *conn)
{ {
int resend_count = 0; int resend_count = 0;
@ -148,7 +159,7 @@ static void conn_resend(NETCONNECTION *conn)
while(item) while(item)
{ {
NETCHUNKDATA *resend = item; NETCHUNKDATA *resend = item;
conn_queue_chunk(conn, resend->flags|NET_CHUNKFLAG_RESEND, resend->data_size, resend->data); conn_resend_chunk(conn, resend);
item = ringbuf_next(conn->buffer, item); item = ringbuf_next(conn->buffer, item);
max--; max--;
resend_count++; resend_count++;
@ -156,7 +167,8 @@ static void conn_resend(NETCONNECTION *conn)
break; break;
} }
dbg_msg("conn", "resent %d packets", resend_count); if(config.debug)
dbg_msg("conn", "resent %d packets", resend_count);
} }
int conn_connect(NETCONNECTION *conn, NETADDR *addr) int conn_connect(NETCONNECTION *conn, NETADDR *addr)
@ -240,7 +252,7 @@ int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR *addr)
{ {
/* send response and init connection */ /* send response and init connection */
conn_reset(conn); conn_reset(conn);
conn->state = NET_CONNSTATE_ONLINE; conn->state = NET_CONNSTATE_PENDING;
conn->peeraddr = *addr; conn->peeraddr = *addr;
conn->last_send_time = now; conn->last_send_time = now;
conn->last_recv_time = now; conn->last_recv_time = now;
@ -272,9 +284,19 @@ int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR *addr)
} }
} }
} }
else
{
if(conn->state == NET_CONNSTATE_PENDING)
{
conn->state = NET_CONNSTATE_ONLINE;
if(config.debug)
dbg_msg("connection", "connecting online");
}
}
if(conn->state == NET_CONNSTATE_ONLINE) if(conn->state == NET_CONNSTATE_ONLINE)
{ {
conn_ack(conn, packet->ack); conn_ack(conn, packet->ack);
} }
@ -288,31 +310,6 @@ int conn_update(NETCONNECTION *conn)
if(conn->state == NET_CONNSTATE_OFFLINE || conn->state == NET_CONNSTATE_ERROR) if(conn->state == NET_CONNSTATE_OFFLINE || conn->state == NET_CONNSTATE_ERROR)
return 0; return 0;
/* watch out for major hitches */
{
/* TODO: fix this */
/*
int64 delta = now-conn->last_update_time;
if(conn->last_update_time && delta > time_freq()/2)
{
RINGBUFFER_ITEM *item = conn->buffer.first;
dbg_msg("conn", "hitch %d", (int)((delta*1000)/time_freq()));
conn->last_recv_time += delta;
while(item)
{
NETPACKETDATA *resend = (NETPACKETDATA *)rb_item_data(item);
resend->first_send_time += delta;
item = item->next;
}
}
conn->last_update_time = now;
*/
}
/* check for timeout */ /* check for timeout */
if(conn->state != NET_CONNSTATE_OFFLINE && if(conn->state != NET_CONNSTATE_OFFLINE &&
conn->state != NET_CONNSTATE_CONNECT && conn->state != NET_CONNSTATE_CONNECT &&
@ -322,21 +319,29 @@ int conn_update(NETCONNECTION *conn)
conn_set_error(conn, "timeout"); conn_set_error(conn, "timeout");
} }
/* fix resends */
if(ringbuf_first(conn->buffer)) if(ringbuf_first(conn->buffer))
{ {
/* TODO: fix this */
NETCHUNKDATA *resend = (NETCHUNKDATA *)ringbuf_first(conn->buffer); NETCHUNKDATA *resend = (NETCHUNKDATA *)ringbuf_first(conn->buffer);
/* check if we have some really old stuff laying around and abort if not acked */
if(now-resend->first_send_time > time_freq()*10) if(now-resend->first_send_time > time_freq()*10)
{ {
conn->state = NET_CONNSTATE_ERROR; conn->state = NET_CONNSTATE_ERROR;
conn_set_error(conn, "too weak connection (not acked for 10 seconds)"); conn_set_error(conn, "too weak connection (not acked for 10 seconds)");
} }
else
{
/* resend packet if we havn't got it acked in 1 second */
if(now-resend->last_send_time > time_freq())
conn_resend_chunk(conn, resend);
}
} }
/* send keep alives if nothing has happend for 1000ms */ /* send keep alives if nothing has happend for 250ms */
if(conn->state == NET_CONNSTATE_ONLINE) if(conn->state == NET_CONNSTATE_ONLINE)
{ {
if(time_get()-conn->last_send_time > time_freq()/2) /* flush connection after 250ms if needed */ if(time_get()-conn->last_send_time > time_freq()/2) /* flush connection after 500ms if needed */
{ {
int num_flushed_chunks = conn_flush(conn); int num_flushed_chunks = conn_flush(conn);
if(num_flushed_chunks && config.debug) if(num_flushed_chunks && config.debug)
@ -350,14 +355,11 @@ int conn_update(NETCONNECTION *conn)
{ {
if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect every 500ms */ if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect every 500ms */
conn_send_control(conn, NET_CTRLMSG_CONNECT, 0, 0); conn_send_control(conn, NET_CTRLMSG_CONNECT, 0, 0);
/*conn_send(conn, NETWORK_PACKETFLAG_CONNECT, 0, 0);*/
} }
else if(conn->state == NET_CONNSTATE_CONNECTACCEPTED) else if(conn->state == NET_CONNSTATE_PENDING)
{ {
if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect/accept every 500ms */ if(time_get()-conn->last_send_time > time_freq()/2) /* send a new connect/accept every 500ms */
conn_send_control(conn, NET_CTRLMSG_CONNECTACCEPT, 0, 0); conn_send_control(conn, NET_CTRLMSG_CONNECTACCEPT, 0, 0);
/*conn_send(conn, NETWORK_PACKETFLAG_CONNECT|NETWORK_PACKETFLAG_ACCEPT, 0, 0);*/
} }
return 0; return 0;

View file

@ -18,6 +18,8 @@ CURRENT:
unsigned char flags_size; // 2bit flags, 6 bit size unsigned char flags_size; // 2bit flags, 6 bit size
unsigned char size_seq; // 4bit size, 4bit seq unsigned char size_seq; // 4bit size, 4bit seq
(unsigned char seq;) // 8bit seq, if vital flag is set (unsigned char seq;) // 8bit seq, if vital flag is set
*/ */
enum enum
@ -35,7 +37,7 @@ enum
NET_CONNSTATE_OFFLINE=0, NET_CONNSTATE_OFFLINE=0,
NET_CONNSTATE_CONNECT=1, NET_CONNSTATE_CONNECT=1,
NET_CONNSTATE_CONNECTACCEPTED=2, NET_CONNSTATE_PENDING=2,
NET_CONNSTATE_ONLINE=3, NET_CONNSTATE_ONLINE=3,
NET_CONNSTATE_ERROR=4, NET_CONNSTATE_ERROR=4,
@ -84,6 +86,7 @@ typedef struct
unsigned char *data; unsigned char *data;
int sequence; int sequence;
int64 last_send_time;
int64 first_send_time; int64 first_send_time;
} NETCHUNKDATA; } NETCHUNKDATA;

View file

@ -773,7 +773,7 @@ void GAMECLIENT::send_info(bool start)
msg.use_custom_color = config.player_use_custom_color; msg.use_custom_color = config.player_use_custom_color;
msg.color_body = config.player_color_body; msg.color_body = config.player_color_body;
msg.color_feet = config.player_color_feet; msg.color_feet = config.player_color_feet;
msg.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH); msg.pack(MSGFLAG_VITAL);
} }
else else
{ {

View file

@ -3,10 +3,10 @@
#include <cstdlib> #include <cstdlib>
struct packet struct PACKET
{ {
packet *prev; PACKET *prev;
packet *next; PACKET *next;
NETADDR send_to; NETADDR send_to;
int64 timestamp; int64 timestamp;
@ -15,8 +15,8 @@ struct packet
char data[1]; char data[1];
}; };
static packet *first = (packet *)0; static PACKET *first = (PACKET *)0;
static packet *last = (packet *)0; static PACKET *last = (PACKET *)0;
static int current_latency = 0; static int current_latency = 0;
static int debug = 0; static int debug = 0;
@ -40,11 +40,11 @@ int run(int port, NETADDR dest)
if(bytes <= 0) if(bytes <= 0)
break; break;
//if((rand()%10) == 0) // drop the packet if((rand()%2) == 0) // drop the packet
// continue; continue;
// create new packet // create new packet
packet *p = (packet *)mem_alloc(sizeof(packet)+bytes, 1); PACKET *p = (PACKET *)mem_alloc(sizeof(PACKET)+bytes, 1);
if(net_addr_comp(&from, &dest) == 0) if(net_addr_comp(&from, &dest) == 0)
{ {
@ -95,7 +95,7 @@ int run(int port, NETADDR dest)
//dbg_msg("crapnet", "%p", first); //dbg_msg("crapnet", "%p", first);
if(first && (time_get()-first->timestamp) > current_latency) if(first && (time_get()-first->timestamp) > current_latency)
{ {
packet *p = first; PACKET *p = first;
first = first->next; first = first->next;
if(first) if(first)
first->prev = 0; first->prev = 0;
@ -117,8 +117,8 @@ int run(int port, NETADDR dest)
// update lag // update lag
double flux = rand()/(double)RAND_MAX; double flux = rand()/(double)RAND_MAX;
int ms_spike = 0; int ms_spike = 0;
int ms_flux = 20; int ms_flux = 100;
int ms_ping = 50; int ms_ping = 100;
current_latency = ((time_freq()*ms_ping)/1000) + (int64)(((time_freq()*ms_flux)/1000)*flux); // 50ms current_latency = ((time_freq()*ms_ping)/1000) + (int64)(((time_freq()*ms_flux)/1000)*flux); // 50ms
if(ms_spike && (p->id%100) == 0) if(ms_spike && (p->id%100) == 0)