elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  WSAError: 10004 ; Blocking sockets
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: WSAError: 10004 ; Blocking sockets  (Leído 2,488 veces)
Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
WSAError: 10004 ; Blocking sockets
« en: 14 Junio 2016, 19:09 pm »

Hola a todos,

Bueno estoy trabajando con un servidor proxy HTTP y parece que hay problemas con los sockets al hacer accept(), antes de nada decir que uso el navegador para conectar al servidor, decir que es un proxy recibe petición del navegador carga la peticion y la manda al servidor con CURL, y mando la respuesta al socket.

WSAEINTR 10004 Interrupted function call: A blocking operation was interrupted by a call to WSACancelBlockingCall.

Esto quiere decir que alguien ha llamado llamado a WSACancelBlockingCall y las funciones de espera asociadas a sockets no funcionan como recv o accept ya que son funciones que se bloquean hasta obtener una respuesta a no ser que se las ponga un temporizador máximo de espera, si se llama a esta función esa espera desaparece haciéndolas inútiles.

El código:

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

Las 2 primeras requests del cliente las recibe y responde con éxito pero a partir de la segunda request tras enviar la respuesta llama a WSACancelBlockingCall, ¿porque? ¿cómo evitarlo?.

Una vez que sale el error 10004 el bucle itera produciendo errores 10093 (WSANOTINITIALISED).

Puede que sea llamada en HTTPSession:

Código
  1. void HTTPSession(SOCKET victimSocket, std::string victimIP, STATUS& controller)
  2. {
  3. CHAR headerBuffer[8192];
  4. memset(headerBuffer, '\0', 8192);
  5.  
  6. INT rlen = recv(victimSocket, headerBuffer, 8192, NULL);
  7. ...
  8. }
  9.  

Reading: http://www.sockets.com/winsock.htm#CancelBlockingCall

Estoy probando a ponerlo en blocking mode de nuevo con:
Código
  1. ULONG iMode = 0;//blocking mode
  2. ioctlsocket(victimSocket, FIONBIO, &iMode);
  3.  
Pero falla de nuevo por el error 10004.

Saludos.

Edito: Bueno, decir que esta parcialmente arreglado con una chapuza que trataré de mejorar, lo que vengo a hacer es reestablecer el modo block despues de cada accept para el socket "victimSocket", así si al llamar al thread y hacer el recv() se llama a cancelblocking rapidamente se reestablecera tras obtener la respuesta de recv. Hay que llamar a WSAStartup pues la llamada a cancelblocking llama a WSACleanup().

Código
  1. ULONG iMode = 0;//block mode
  2. while (status != DISABLE)
  3. {
  4. victimSocket = accept(serverSocket, (sockaddr*)&victimAddr, &len);
  5.  
  6. if (victimSocket != INVALID_SOCKET)
  7. {
  8. std::thread t(HTTPSession, victimSocket, inet_ntoa(victimAddr.sin_addr), status);
  9. t.detach();
  10. }
  11.  
  12. WSAStartup(MAKEWORD(2, 0), &wsa);
  13. INT iResult = ioctlsocket(victimSocket, FIONBIO, &iMode);
  14. if (iResult != NO_ERROR)
  15. printf("ioctlsocket failed with error: %ld %d\n", iResult, GetLastError());
  16. }
  17.  

PD: He probado a hacerlo solo cuando de error y no funciona, sería curar con esto prevenimos siempre pero evidentemente no me convence tener que llamar a WSAStartup en un bucle, buscaré mejores alternativas..

Edito otra vez: NO hace falta usar ioctlsocket para ponerlo en modo block, solo con llamar a WSAStartup ya funciona y no da error :""""(, la cosa es que parece que para cada socket hay que llamar a WSAStartup así que meteré la llamada en HTTPSession.


« Última modificación: 15 Junio 2016, 11:56 am por Kaxperday » En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
ivancea96


Desconectado Desconectado

Mensajes: 3.412


ASMático


Ver Perfil WWW
Re: WSAError: 10004 ; Blocking sockets
« Respuesta #1 en: 15 Junio 2016, 18:38 pm »

Basta llamar WSAStartup 1 vez por programa, salvo que realmente necesites hacerlo varias veces.
Si llamarlo más veces te soluciona el problema, ten en cuenta que el verdadero error ha de seguir ahí.


En línea

Kaxperday


Desconectado Desconectado

Mensajes: 702


The man in the Middle


Ver Perfil WWW
Re: WSAError: 10004 ; Blocking sockets
« Respuesta #2 en: 16 Junio 2016, 07:56 am »

Hola ivancea,

Parece que ya está solucionado eramás bien un despiste, pues en HTTPSession al final de la función llamaba a WSACleanup() y por eso daba  el error de nonblocking sockets (que lo debería de llamar WSACleanup()) y tras desbloquear los sockets, desinicializaba winsock y tenía que llamar de nuevo a WSAStartup, así que ya sabeis poned igual numero de WSAStartup y de WSACleanup para no llevaros sustos XD.

Saludos y gracias por la respuesta.
En línea

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[SOLUCIONADO] [Duda] De Threads, Swing, y Non Blocking Calls
Java
RyogiShiki 1 2,816 Último mensaje 15 Noviembre 2011, 14:56 pm
por RyogiShiki
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines