Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: AlbertoBSD en 21 Septiembre 2016, 21:10 pm



Título: CreateThread para Servevidor en C
Publicado por: AlbertoBSD en 21 Septiembre 2016, 21:10 pm
Que tal Pongo aqui la solucion que encontre al problema de no tener fork en Windows, la solucion es CreateThread de la winapi



Código
  1.    if(listen(ListenSocket, BACKLOG) == SOCKET_ERROR) {
  2. printf("listen failed with error: %ld\n", WSAGetLastError());
  3. closesocket(ListenSocket);
  4. WSACleanup();
  5.        return 1;
  6.    }
  7. while(entrar) {//Entrar es true solo se cambia por otro segmento del codigo en caso de que queramos finalizar con el hilo principal
  8. b = sizeof(struct sockaddr_in);
  9. client = accept(ListenSocket,(SOCKADDR *) service,&b);
  10. if(client == INVALID_SOCKET) {
  11. exit(1);
  12. }
  13. toThread = malloc(sizeof(SOCKET));
  14. memcpy(toThread,&client,sizeof(SOCKET));// Copiamos la variable socket principal para pasarla al thread
  15. hThread = CreateThread(
  16.            NULL,                   // default security attributes
  17.            0,                      // use default stack size  
  18.            client_funtion,       // thread function name
  19.            toThread,          // argument to thread function
  20.            0,                      // use default creation flags
  21.            &dwThreadId);   // returns the thread identifier
  22. printf("Thread ID %u\n",dwThreadId);
  23. if(hThread == NULL) {
  24.           free(toThread);
  25.   exit(0)
  26.        }
  27. }
  28.    closesocket(ListenSocket);

hay que tener en cuenta que necesitasmos una funcion para el Thread:

Código
  1. DWORD WINAPI client_funtion( LPVOID lpParam ) {
  2. //Variables
  3. // aqui recivir datos y procesarlos, se puede llamar a otras funciones que sean Thread safe
  4. }
  5.  

Si no queremos que el hilo principal se "preocupe" por cerrar estas conexiones y terminar con el hilo podemos poner lo siguiente:

Código
  1. DWORD WINAPI client_funtion( LPVOID lpParam ) {
  2. HANDLE thread_id;
  3. thread_id = GetCurrentThread();
  4. //Otras variables
  5. //codigo aque para procesar al cliente correctamente
  6.  
  7. free(lpParam); //Si lpParam es un parametro que tenemos que liberar entonces Free
  8.  
  9. CloseHandle(thread_id); //Terminamos con nuestro propio Thread
  10. }
  11.  

Me base en el ejemplo puesto aqui:

http://foro.elhacker.net/programacion_cc/createthread_o_createprocess-t458039.0.html

Saludos


Título: Re: CreateThread para Servevidor en C
Publicado por: Kaxperday en 22 Septiembre 2016, 11:41 am
Buenas Alberto,

Pues me parece que para windows la mejor opcion para lo que buscas es esa, dando por hecho que para procesar un cliente es mejor crear un thread que un proceso. Yo trabajo con C++ y en su lugar lo hago con std::thread que lo veo mas sencillo y maleable, din embargo para C no me viene ahora a la cabeza otra funcion para crear threads que esa,te recomendaría pasar a C++ XD.

Te dejo aquí un ejemplo de mi thread servidor sslstrip en C++:

Código
  1. void SSLStrip::Run(std::string serverIP, UINT serverPort)
  2. {
  3. //CookieCleaner::GetInstance()->SetEnabled(TRUE);
  4. WSADATA wsa;
  5. SOCKET serverSocket;
  6. sockaddr_in serverAddr;
  7.  
  8. WSAStartup(MAKEWORD(2, 0), &wsa);
  9. memset(&serverAddr, 0, sizeof(serverAddr));
  10.  
  11. if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) != INVALID_SOCKET)
  12. {
  13. serverAddr.sin_family = AF_INET;
  14. serverAddr.sin_port = htons(serverPort);
  15. serverAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());
  16.  
  17. if (::bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) != SOCKET_ERROR)
  18. {
  19. if (listen(serverSocket, MAXIMUM_SNIFFER_VICTIMS) != SOCKET_ERROR)
  20. {
  21. SOCKET victimSocket;
  22. sockaddr_in victimAddr;
  23. victimAddr.sin_family = AF_INET;
  24. INT len = sizeof(victimAddr);
  25.  
  26. while (status != DISABLE_SSLSTRIP)
  27. {
  28. victimSocket = accept(serverSocket, (sockaddr*)&victimAddr, &len);
  29.  
  30. if (victimSocket != INVALID_SOCKET)
  31. {
  32. std::thread t(HTTPSession, victimSocket, inet_ntoa(victimAddr.sin_addr), status);
  33. t.detach();
  34. }
  35. }
  36. }
  37. }
  38. closesocket(serverSocket);
  39. }
  40.  
  41. WSACleanup();
  42. }
  43.  

Ahora que me fijo creo que pondré un if en WSAStartup por si da error que no haga el bloque y meteré el WSACleanup al final del bloque del if.

Un saludo y animo.


Título: Re: CreateThread para Servevidor en C
Publicado por: AlbertoBSD en 22 Septiembre 2016, 16:22 pm
Pues en teoria estoy creando un thread y no un proceso hay una funcion en windows que hace precisamente eso (CreateProcess) el tema lo trate aqui:

https://foro.elhacker.net/programacion_cc/createthread_o_createprocess-t458039.0.html

Y si al final decidi usar los threads al estilo de windows y funciona bastante bien. ya que lo termine probare el metodo que indicas.

Saludos!