quake3 源码分析(六)
--网络数据传输与接收
数据结构:
#define MAX_LOOPBACK 16
typedef struct {
byte data[MAX_PACKETLEN];// MAX_PACKETLEN = 1400
int datalen;
} loopmsg_t;
typedef struct {
loopmsg_t msgs[MAX_LOOPBACK];
int get, send;//循环队列,指示接收或发送消息的位置
} loopback_t;
loopback_t loopbacks[2];//使用两个队列:一个客户端用,一个服务器端用
//接收本地数据
qboolean NET_GetLoopPacket (netsrc_t sock, netadr_t *net_from, msg_t *net_message)
{
loop = &loopbacks[sock];// NS_CLIENT = 0,NS_SERVER = 1
if (loop->send - loop->get > MAX_LOOPBACK)
loop->get = loop->send - MAX_LOOPBACK;
if (loop->get >= loop->send)
return qfalse;
i = loop->get & (MAX_LOOPBACK-1);
loop->get++;
Com_Memcpy (net_message->data, loop->msgs[i].data, loop->msgs[i].datalen);//拷贝数据到缓冲
net_message->cursize = loop->msgs[i].datalen;
Com_Memset (net_from, 0, sizeof(*net_from));
net_from->type = NA_LOOPBACK;
return qtrue;
}
//发送本地数据
void NET_SendLoopPacket (netsrc_t sock, int length, const void *data, netadr_t to)
{
loop = &loopbacks[sock^1];
i = loop->send & (MAX_LOOPBACK-1);
loop->send++;
Com_Memcpy (loop->msgs[i].data, data, length);//将数据拷贝到缓冲队列
loop->msgs[i].datalen = length;
}
//发送网络数据
void Sys_SendPacket( int length, const void *data, netadr_t to )
{
//根据发送数据的类型进行网络地址到SOCEKT地址的传换
//调用sendto函数发送数据,
if( usingSocks && to.type == NA_IP ) {
socksBuf[0] = 0; // reserved
socksBuf[1] = 0;
socksBuf[2] = 0; // fragment (not fragmented)
socksBuf[3] = 1; // address type: IPV4
*(int *)&socksBuf[4] = ((struct sockaddr_in *)&addr)->sin_addr.s_addr;
*(short *)&socksBuf[8] = ((struct sockaddr_in *)&addr)->sin_port;
memcpy( &socksBuf[10], data, length );
ret = sendto( net_socket, socksBuf, length+10, 0, &socksRelayAddr, sizeof(socksRelayAddr) );
}
else {
ret = sendto( net_socket, data, length, 0, &addr, sizeof(addr) );
}
//进行出错处理
}