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

View file

@ -72,9 +72,12 @@ int conn_flush(NETCONNECTION *conn)
int num_chunks = conn->construct.num_chunks;
if(!num_chunks && !conn->construct.flags)
return 0;
/* send of the packets */
conn->construct.ack = conn->ack;
send_packet(conn->socket, &conn->peeraddr, &conn->construct);
/* update send times */
conn->last_send_time = time_get();
/* 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)
{
unsigned char *chunk_data;
/* 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))
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 = (unsigned char *)(resend+1);
resend->first_send_time = time_get();
resend->last_send_time = resend->first_send_time;
mem_copy(resend->data, data, data_size);
}
else
@ -134,12 +139,18 @@ static void conn_send_control(NETCONNECTION *conn, int controlmsg, const void *e
construct.data_size = 1+extra_size;
construct.chunk_data[0] = controlmsg;
mem_copy(&construct.chunk_data[1], extra, extra_size);
/* send the control message */
send_packet(conn->socket, &conn->peeraddr, &construct);
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)
{
int resend_count = 0;
@ -148,7 +159,7 @@ static void conn_resend(NETCONNECTION *conn)
while(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);
max--;
resend_count++;
@ -156,7 +167,8 @@ static void conn_resend(NETCONNECTION *conn)
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)
@ -240,7 +252,7 @@ int conn_feed(NETCONNECTION *conn, NETPACKETCONSTRUCT *packet, NETADDR *addr)
{
/* send response and init connection */
conn_reset(conn);
conn->state = NET_CONNSTATE_ONLINE;
conn->state = NET_CONNSTATE_PENDING;
conn->peeraddr = *addr;
conn->last_send_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)
{
conn_ack(conn, packet->ack);
}
@ -287,31 +309,6 @@ int conn_update(NETCONNECTION *conn)
if(conn->state == NET_CONNSTATE_OFFLINE || conn->state == NET_CONNSTATE_ERROR)
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 */
if(conn->state != NET_CONNSTATE_OFFLINE &&
@ -322,21 +319,29 @@ int conn_update(NETCONNECTION *conn)
conn_set_error(conn, "timeout");
}
/* fix resends */
if(ringbuf_first(conn->buffer))
{
/* TODO: fix this */
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)
{
conn->state = NET_CONNSTATE_ERROR;
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(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);
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 */
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 */
conn_send_control(conn, NET_CTRLMSG_CONNECTACCEPT, 0, 0);
/*conn_send(conn, NETWORK_PACKETFLAG_CONNECT|NETWORK_PACKETFLAG_ACCEPT, 0, 0);*/
}
return 0;

View file

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

View file

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

View file

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