Я пишу сетевую игру на C++, используя Winsock UDP сокеты, и у меня есть проблема, что каждый раз, когда вызывается sendto(), она увеличивает использование памяти необратимым образом , Самое странное, что появляется только на клиенте, на сервере нет проблем, хотя он использует почти идентичный сетевой код.C/C++ Winsock UDP - 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 (он кодирует float до 4 байтов) также не важны, без sendto() все работает нормально. Существуют ли какие-либо возможные исправления, кроме использования Winsock/UDP или уничтожения и создания сокета снова каждый раз, когда использование памяти слишком велико?
Я полагаю, что после того, как сервер sendto отправит что-то обратно, и клиент обрабатывает данные? Это может быть проблема? И насколько велика утечка? Что такое определение 'data' и' RQBUFFER'? – Inspired
RQBUFFER теперь 32, данные: данные char [RQBUFFER]; Я тестировал его в ситуации, когда сервер был отключен (ответов не получено), и он игнорировался на клиенте - ничего не меняется. – user1262737
При запуске отладки Debug в отладчике попробуйте использовать [Visual Leak Detector] (https://vld.codeplex.com/) - он покажет вам, какая память просочилась, и где в вашем коде выделяется эта память. Это должно помочь выявить проблему. – icabod