Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: ShinyDavid en 1 Julio 2015, 04:10 am



Título: Consumo excesivo de ram en thread y sockets
Publicado por: ShinyDavid en 1 Julio 2015, 04:10 am
Buenas noches.

Hola tengo una duda, recientemente estoy programando en C un cliente para estar a la escucha de cuando inicie el servidor se conecte automaticamente, sin embargo ya realizado el trabajo el cliente empieza a ocupar mucha ram cuando no se conecta, cada que se repite la funcion de conexion automatica se toman aproximadamente 128 kbs mas, no es mucho pero deje trabajandolo un dia completo y me tomo la mitad de la ram que tenia mi pc, lo que quiero saber es por que y como solucionarlo, este proyecto es mi primer programa en C que es un poco mas complejo ya que nunca habia usado Threads ni sockets, de antemano muchas gracias.

Código:
DWORD WINAPI CheckConexion(LPVOID LPARAM)
{
    while(1)
    {
        if(ConnectList != 1)
        {
            ConnectList = ReIntConexion();
            if(ConnectList != 1)
                Sleep(TIME_RECON);
            else
            {
                AlreadyCheckList = 0;
                ExitThread(CheckConex);
                CloseHandle(CheckCC);
                return 1;
            }
        }
    }
    return 0;
}

int ReIntConexion()
{
    printf("ejecutado");
    if(ConnectList == 1)
        return 0;

    if(AlreadyRecibeDat == 1)
        return 0;

    shutdown(sock, SD_BOTH);
    closesocket(sock);
    WSACleanup();

    WSAStartup(MAKEWORD (2, 2), &wsa);
    if((host = gethostbyname(HostOrIPCo)) == NULL)
    {
        if(AlreadyCheckList==0)
        {
            ExitThread(CheckConex);
            CloseHandle(CheckCC);
            CheckCC=CreateThread(NULL,0,CheckConexion,NULL,0,& CheckConex);
            AlreadyCheckList = 1;
        }
        closesocket(sock);
        WSACleanup();
        return -1;
    }

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == -1)
    {
        if(AlreadyCheckList==0)
        {
            ExitThread(CheckConex);
            CloseHandle(CheckCC);
            CheckCC=CreateThread(NULL,0,CheckConexion,NULL,0,&CheckConex);
            AlreadyCheckList = 1;
        }
        closesocket(sock);
        WSACleanup();
        return -1;
    }

    direc.sin_family = AF_INET;
    direc.sin_port = htons(PORT_CONE);
    direc.sin_addr = *((struct in_addr *)host->h_addr);
    memset(direc.sin_zero, 0, 8);
    conex = connect(sock,(struct sockaddr *)&direc, sizeof(struct sockaddr));

    if(conex == -1)
    {
        if(AlreadyCheckList==0)
        {
            ExitThread(CheckConex);
            CloseHandle(CheckCC);
            CheckCC=CreateThread(NULL,0,CheckConexion,NULL,0,& CheckConex);
            AlreadyCheckList = 1;
        }
        shutdown (sock, SD_BOTH);
        closesocket(sock);
        WSACleanup();
        return -1;
    }

    ReceData=CreateThread(NULL,0,RecepcionDatos,NULL,0,& ReceData_);
    AlreadyRecibeDat = 1;
    return 1;
}

Gracias.


Título: Re: Consumo excesivo de ram en thread y sockets
Publicado por: ivancea96 en 1 Julio 2015, 13:36 pm
Código
  1. if(AlreadyCheckList==0)
  2. {
  3.    ExitThread(CheckConex);
  4.    CloseHandle(CheckCC);
  5.    CheckCC=CreateThread(NULL,0,CheckConexion,NULL,0,& CheckConex);
  6.    AlreadyCheckList = 1;
  7. }

ExitThread() (https://msdn.microsoft.com/es-es/library/windows/desktop/ms682659%28v=vs.85%29.aspx) cierra el thread actual. El parámetro que recibe es un código de error, no un HANDLE.

De cualquier forma, te recomendaría no cerrar threads de ese modo, y terminar ls funciones limpiamente. Especialmente porque es más 'legible'. Además, si programases en C++, los objetos no se destruirían con ExitThread.


Título: Re: Consumo excesivo de ram en thread y sockets
Publicado por: ShinyDavid en 1 Julio 2015, 15:26 pm
Código
  1. if(AlreadyCheckList==0)
  2. {
  3.    ExitThread(CheckConex);
  4.    CloseHandle(CheckCC);
  5.    CheckCC=CreateThread(NULL,0,CheckConexion,NULL,0,& CheckConex);
  6.    AlreadyCheckList = 1;
  7. }

ExitThread() (https://msdn.microsoft.com/es-es/library/windows/desktop/ms682659%28v=vs.85%29.aspx) cierra el thread actual. El parámetro que recibe es un código de error, no un HANDLE.

De cualquier forma, te recomendaría no cerrar threads de ese modo, y terminar ls funciones limpiamente. Especialmente porque es más 'legible'. Además, si programases en C++, los objetos no se destruirían con ExitThread.

Gracias de hecho antes lo tenia sin ninguna de estas dos funciones
Código:
ExitThread(CheckConex);
    CloseHandle(CheckCC);


El problema es que como me seguia consuimiendo la ram decidi ponerlos para ver si no era el tema de los thread pero al parecer no igual volvere a quitar las funciones pero aun sigo confundido por que me consume tanta ram  :(


Título: Re: Consumo excesivo de ram en thread y sockets
Publicado por: ivancea96 en 1 Julio 2015, 15:43 pm
Viendo así el código es difícil decirlo xD

Como dato, decir que, si no necesitas el HANDLE del thread para nada, puedes cerrarlo nada más crear el thread. El HANDLE es un identificador, cerrarlo no cerrará el thread.

WSAStartup() solo hay que llamarlo 1 vez antes de usar sockets, y WSACleanup() solo 1 vez cuando hayas acabado con ellos. Lo que quiere decir: 1 vez al comienzo del programa, y 1 vez al final. Te recomendaría sacarlo de las funciones, y ponerlo en el main, el menos, de momento.

No se como tienes estructurado el programa, pero cuidado con abusar de los threads. Tal vez prefieras tener solo un par de threads <fijos>, que se sincronicen entre sí con alguna variable global.

Si sigues queriendo utilizarlos como los tienes ahí, ponme el código del main, o donde empieces todo, para ver como va.


Título: Re: Consumo excesivo de ram en thread y sockets
Publicado por: ShinyDavid en 1 Julio 2015, 22:30 pm
Muhisimas gracias por tu respuesta ya se pudo solucionar hice lo que me dijiste, solo uso WSA al inicio y final y ya no usa memoria a lo loco ya es aceptable y no aumenta como adicional si quite los handles y deje que los thread terminaran solos si uso variables globales para ello, de verdad gracias  ;D ;-) lmL