我正在使用 Winsock UDP 套接字在 C++ 中编写一个网络游戏,我有一个问题,每次调用 sendto() 时,它都会以不可逆的方式增加内存使用量。最奇怪的是,它只出现在客户端,即使它使用几乎相同的网络代码,在服务器上也没有问题。
这是创建连接的客户端类的构造函数(我无法显示整个代码,因为它更大而且它不是开源项目):
Client(){
nospawn = true;
status = 0;
hThread = 0;
firstrs = NULL;
lastrs = NULL;
if (WSAStartup(0x0101, &rdata) != 0) exit(WSAGetLastError());
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd == INVALID_SOCKET) exit(WSAGetLastError());
gethostname(host_name, sizeof(host_name));
hp = gethostbyname(host_name);
FILE * file;
BYTE * data;
fopen("config.txt", "rb" );
data= (BYTE*)malloc (15);
fread( data, 15, 1, file );
fclose( file );
memset((void *)&server, '\0', sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(8334);
server.sin_addr.S_un.S_un_b.s_b1
= (unsigned char)(((int)data[0]-48)*100+((int)data[1]-48)*10+(int)data[2]-48);
server.sin_addr.S_un.S_un_b.s_b2
= (unsigned char)(((int)data[4]-48)*100+((int)data[5]-48)*10+(int)data[6]-48);
server.sin_addr.S_un.S_un_b.s_b3
= (unsigned char)(((int)data[8]-48)*100+((int)data[9]-48)*10+(int)data[10]-48);
server.sin_addr.S_un.S_un_b.s_b4
= (unsigned char)(((int)data[12]-48)*100+((int)data[13]-48)*10+(int)data[14]-48);
/* Clear out client struct */
memset((void *)&client, '\0', sizeof(struct sockaddr_in));
client.sin_family = AF_INET;
client.sin_port = htons(0);
client.sin_addr.S_un.S_un_b.s_b1 = hp->h_addr_list[0][0];
client.sin_addr.S_un.S_un_b.s_b2 = hp->h_addr_list[0][1];
client.sin_addr.S_un.S_un_b.s_b3 = hp->h_addr_list[0][2];
client.sin_addr.S_un.S_un_b.s_b4 = hp->h_addr_list[0][3];
server_length = sizeof(struct sockaddr_in);
if (bind(sd, (struct sockaddr *)&client, sizeof(struct sockaddr_in))==-1){
closesocket(sd);
WSACleanup();
exit(WSAGetLastError());
};
}`
以及向服务器发送数据的函数:
void sendCRequest(){
int sum = 0;
unsigned char c1,c2,c3,c4;
if (ludzie[0].ster[S_RIGHT]) sum+=1;
if (ludzie[0].ster[S_LEFT]) sum+=2;
if (ludzie[0].ster[S_UP]) sum+=4;
if (ludzie[0].ster[S_DOWN]) sum+=8;
if (ludzie[0].ster[S_RUN]) sum+=16;
if (ludzie[0].ster[S_ENTER]) sum+=32;
if (ludzie[0].ster[S_SHOT]) sum+=64;
if (ludzie[0].ster[S_RELOAD]) sum+=128;
if (ludzie[0].ster[S_SHOT]){
float depth;
GLdouble modelMatrix [16];
GLdouble projMatrix [16];
GLdouble dx,dy,dz;
GLint viewport [4];
glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);
glGetIntegerv(GL_VIEWPORT,viewport);
glReadPixels( mx, screendy*2-my, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth );
gluUnProject(mx,screendy*2-my,depth,modelMatrix,projMatrix,viewport,&dx,&dy,&dz);
//x
floatEnc(dx,&c1,&c2,&c3,&c4);
data[16]=c1; data[17]=c2; data[18]=c3; data[19]=c4;
//y
floatEnc(dy,&c1,&c2,&c3,&c4);
data[20]=c1; data[21]=c2; data[22]=c3; data[23]=c4;
//z
floatEnc(dz,&c1,&c2,&c3,&c4);
data[24]=c1; data[25]=c2; data[26]=c3; data[27]=c4;
}
data[0] = 'C';
for (int i=1;i<9;i++) data[i]=auth[i-1];
data[10] = (char)sum;
data[11]=ludzie[0].ster[S_SPACE]?'1':'0';
floatEnc(ludzie[0].r,&c1,&c2,&c3,&c4);
data[12]=c1; data[13]=c2; data[14]=c3; data[15]=c4;
sendto(sd, data, RQBUFFER, 0, (struct sockaddr *)&server, server_length);
}
如果除了 sendto() 之外的所有内容都没有,则没有内存泄漏,因此其余代码不是问题。这些 OpenGL 调用和 floatEnc(它将浮点编码为 4 个字节)也不重要,没有 sendto() 一切正常。除了不使用 Winsock/UDP 或每次内存使用率过高时再次销毁和创建套接字之外,还有其他可能的修复方法吗?