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


 


Tema destacado: Como proteger una cartera - billetera de Bitcoin


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Se me cierra el socket. No veo el motivo.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Se me cierra el socket. No veo el motivo.  (Leído 251 veces)
@XSStringManolo
<svg/onload=alert()>
Colaborador
***
Desconectado Desconectado

Mensajes: 2.171


Turn off the red ligth


Ver Perfil WWW
Se me cierra el socket. No veo el motivo.
« en: 30 Marzo 2020, 01:18 »

Hago lo siguiente:

Creo y guardo el código.
$ nano server.cpp
control + x
enter

Compilo:
$ g++ server.cpp -o server

Doy permisos:
$ chmod +775 server

Ejecuto:
$ ./server 8080

Conecto al server:
$ netcat 127.0.0.1 8080

Envio comando prueba 1:
ls

Envio comando prueba 2:
ls

Envio comando prueba 3:
ls
Ya no lo recibe.

Envio comando prueba 4:
broken pipe

Pruebo por si el server siguiese up:
$ netcat 127.0.0.1 8080
connection refused.

La aplicación se paró pero no encuentro el motivo.

Código
  1. #include <iostream>
  2. #include <sys/types.h>
  3. #include <sys/socket.h>
  4. #include <netinet/in.h>
  5. #include <unistd.h>
  6.  
  7. using namespace std;
  8.  
  9. void callback(int);
  10.  
  11. int main(int argc, char *argv[]) {
  12.  int handlerSocket = 0;
  13.  int newHandlerSocket = 0;
  14.  int puerto = 0;
  15.  int TamIP_Cliente = 0;
  16.  int procesoHijo = 0;
  17.  
  18.  unsigned short int MAX_QUEUE = 5;
  19.  unsigned short int ARGUMENTOS_MIN = 2;
  20.  signed short int ERROR = -1;
  21.  
  22.  struct sockaddr_in IP_Servidor, IP_Cliente;
  23.  
  24. /* Comprueba que no falta el argumento cli */
  25.  if (argc < ARGUMENTOS_MIN) {
  26.    cout << "Puerto de escucha no especificado.\nAñade el puerto de escucha como parámetro en la llamada. Ejemplo:\n./server 8080";
  27.    exit(1);
  28.  }
  29.  
  30.  handlerSocket = socket(AF_INET, SOCK_STREAM, 0);
  31.  
  32.  if (handlerSocket == ERROR) {
  33.    cout << "No se pudo crear el socket.";
  34.    exit(1);
  35.  }
  36.  
  37.  /* Formatea el buffer */
  38.  bzero((char *) &IP_Servidor, sizeof(IP_Servidor));
  39.  
  40.  /* Obtiene el argumento por cli */
  41.  puerto = atoi(argv[1]);
  42.  
  43.  /* socket IPV4 */
  44.  IP_Servidor.sin_family = AF_INET;
  45.  
  46.  /* Enlaza a cualquier dirección local disponible */
  47.  IP_Servidor.sin_addr.s_addr = INADDR_ANY;
  48.  
  49.  /* Fuerza que se utilice el orden correcto en la dirección de memoría */
  50.  IP_Servidor.sin_port = htons(puerto);
  51.  
  52.  if (::bind(handlerSocket, (struct sockaddr *) &IP_Servidor, sizeof(IP_Servidor)) == ERROR) {
  53.    cout << "Error enlazando el servidor";
  54.    exit(1);
  55.  }
  56.  
  57.  listen(handlerSocket, MAX_QUEUE);
  58.  TamIP_Cliente = sizeof(IP_Cliente);
  59.  while (1) {
  60.    newHandlerSocket = accept(handlerSocket, (struct sockaddr *) &IP_Cliente, &TamIP_Cliente);
  61.  
  62.    if (handlerSocket == ERROR) {
  63.      cout << "Error creando nuevo socket";
  64.      exit(1);
  65.    }
  66.  
  67.    procesoHijo = fork();
  68.  
  69.    if (procesoHijo == ERROR) {
  70.      cout << "Error duplicando proceso.";
  71.      exit(1);
  72.    }
  73.  
  74.    if (procesoHijo != ERROR) {
  75.      close(handlerSocket);
  76.      callback(newHandlerSocket);
  77.      exit(0);
  78.    } else {
  79.      close(newHandlerSocket);
  80.    }
  81.  }
  82. return 0;
  83. }
  84.  
  85. void callback (int sock) {
  86.  signed short int n;
  87.  signed short int ERROR = -1;
  88.  char buffer[128000];
  89.  bzero(buffer,128000);
  90.  n = read(sock,buffer,128000);
  91.  
  92.  if (n < ERROR) {
  93.    cout << "El handler del socket contiene errores";
  94.    exit(1);
  95.  }
  96.  
  97.  cout << "Respuesta:" << endl << buffer << endl;
  98.  n = write(sock,"Recivido.",9);
  99.  
  100.  /* Básico. Modificar por popen(); traer sh o incluir intérprete */
  101.  system(buffer);
  102.  
  103.  if (n < ERROR) {
  104.    cout << "No se pudo escribir en el socket.";
  105.    exit(1);
  106.  }
  107. }


« Última modificación: 30 Marzo 2020, 01:23 por @XSStringManolo » En línea

RayR

Desconectado Desconectado

Mensajes: 127


Ver Perfil
Re: Se me cierra el socket. No veo el motivo.
« Respuesta #1 en: 30 Marzo 2020, 04:49 »

Hay algunos errores en tu código. El principal es esta línea:

Código
  1.    if (procesoHijo != ERROR) {

En el if anterior ya verificabas si hubo error, por lo que si llegamos hasta aquí, eso significa necesariamente que fork se ejecutó exitosamente, luego este if sobra, y de hecho, en este caso lo que hace es que la conexión se cierre siempre que no haya error, que es justo lo que está causando tu problema. Lo que siempre se debe hacer después de llamar a fork y comprobar que no falló, es verificar si estamos en el proceso hijo (fork devolvió 0) o en el padre, y actuar en consecuencia.

Tal como está el programa, sólo se acepta un mensaje por conexión, pero por lo que comentas al inicio, no sé si sea lo que quieres. Si no es así, no llames a exit sino hasta que se cumpla cierta condición, como recibir el mensaje "CLOSE".

Edito: porque veo que se me cruzaron dos ideas, y en lo que borraba para corregir, terminé diciendo algo a medias. Lo que quise decir es que el programa tal como está tendrá procesos zombis, porque no hay ningún wait, aunque realmente esto sólo representaría un problema si creas muchos procesos hijos.

Tu función callback no detectará correctamente errores, ya que write y read devuelven -1 cuando algo falló, pero tú estás verificando que devuelvan un valor menor a -1 (ERROR).


« Última modificación: 30 Marzo 2020, 19:39 por RayR » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines