Tema: Servidor C++
Ver Mensaje Individual
  #3 (permalink)  
Antiguo 21/06/2011, 02:24
mariaamo
 
Fecha de Ingreso: junio-2011
Ubicación: Saarbrücken
Mensajes: 9
Antigüedad: 12 años, 11 meses
Puntos: 0
Respuesta: Servidor C++

Tienes razón, pero no he pegado el código porque es algo complejo. Estoy programando un microcontrolador y aunque lo hago en C++, tengo que ceñirme a unas librerías concretas.
En realidad, las funciones son las mismas, con la salvedad de que tengo estar haciendo un "poll" permantente al socket para observar que eventos tienen lugar, y gestinonarlos.

En el main tengo lo siguiente:
Código C++:
Ver original
  1. [CODE]
  2. int main() {
  3.  
  4.     pc.format(8, Serial::None, 1);
  5.     pc.baud(9600);
  6.     EthernetErr NetErr = NetIf.setup();
  7.     if (NetErr) {
  8.         pc.printf("\r\nERROR SETTING UP EHTERNETNETIF...\r\n");
  9.         return 0;
  10.     }
  11.     socket_event();
  12.  
  13.     while (true) { //Necessary to work!.
  14.         Net::poll();
  15.  
  16.     }
  17. }[/CODE]

Estoy haciendo un "poll" continuo de la red, además de llamar a la función "socket_event" que es la siguiente:

Código:


Código C++:
Ver original
  1. //////////////////////////////////////////////
  2. /////Function to create a listener socket/////
  3. //////////////////////////////////////////////
  4.  
  5. int socket_event() { //function to open an event socket
  6.     socket.resetOnEvent();
  7.     socket.setOnEvent(&onTCPSocketEvent_Accept);
  8.     TCPSocketErr err;
  9.     err = socket.bind(Host(IpAddr(134,96,214,36), 10001); //PC IP + PORT ; this socket keeps open listening for another connections
  10.     if (err) {
  11.         pc.printf("\r\nERROR BINDING: %s", err, "/r/n");
  12.         return 0;
  13.     }
  14.     err = socket.listen(); //Starts listening
  15.     if (err) {
  16.         pc.printf("\r\nERROR LISTENING...\r\n");
  17.         return 0;
  18.     }
  19.     pc.printf("\r\nLISTENING...\r\n");
  20.     server_mode=true;
  21.     client_mode=false;
  22.     return 0;
  23. }
Aquí, hago el bind, el listen y llamo a la función que captará el evento "ACCEPT", "onTCPSocketEvent_Accept"

Código C++:
Ver original
  1. [CODE]
  2. ///////////////////////////////////////////
  3. //// Function to handle "ACCEPT" event ////
  4. ///////////////////////////////////////////
  5.  
  6. void onTCPSocketEvent_Accept(TCPSocketEvent e) {
  7.     if ( e == TCPSOCKET_ACCEPT ) {
  8.         pClientSock = new TCPSocket();
  9.         Host Client;
  10.         TCPSocketErr err = socket.accept(&Client, &pClientSock);
  11.         if (err) {
  12.             pc.printf("\r\nERROR ACCEPTING CLIENT...\n\r");//Could not accept client
  13.             return;
  14.         }
  15.  
  16.         pClientSock->setOnEvent(&onTCPSocketEvent); //Setup the new socket events
  17.        
  18.     }
  19. }
  20. [/CODE]

Aquí también abro el socket para el intercambio de información con el cliente (pClientSock) y llamo a la funcion que gestionará los eventos en ese socket , "onTCPSocketEvent":
Código C++:
Ver original
  1. [CODE]////////////////////////////////////////////
  2. //////Function to catch Socket´s Events/////
  3. ////////////////////////////////////////////
  4.  
  5. void onTCPSocketEvent(TCPSocketEvent e) {
  6.     pc.printf("\r\nEvent: %d", e);
  7.     switch (e) {
  8.  
  9.         case TCPSOCKET_CONNECTED: {
  10.             pc.printf("\r\nCONNECTION ESTABLISHED...\r\n");
  11.           int long_sent =socket.send("Tag received", sizeof("Tag received"));
  12.         }
  13.         break;
  14.  
  15.         case TCPSOCKET_WRITEABLE: {
  16.             pc.printf("\n\rCan now write some data\r\n");
  17.            
  18.         }
  19.         break;
  20.  
  21.         case TCPSOCKET_CONRST: {
  22.             pc.printf("\r\nERROR... CONNECTION RESETED...\r\n");
  23.             if (end_NM_config==true) {
  24.                 pc.printf ("voy a cambiar a cliente en CONRST\r\n");
  25.                 socket.close();
  26.                 pClientSock->close();
  27.                 socket_communication();
  28.                 end_NM_config=false;
  29.             } else if (change_mode) {
  30.                 pc.printf(" voy a cambiar a server en el CONRST\r\n");
  31.                 socket.close();
  32.                 socket_event();
  33.                 change_mode=false;
  34.             }
  35.         }
  36.         break;
  37.  
  38.         case TCPSOCKET_CONTIMEOUT:
  39.         case TCPSOCKET_CONABRT: {
  40.             socket.close();
  41.             pClientSock->close();
  42.             socket_communication();
  43.         }
  44.         break;
  45.         case TCPSOCKET_ERROR: {
  46.  
  47.             pc.printf("\r\nERROR...\r\nCLOSING SOCKET\r\n");
  48.             socket.close();
  49.         }
  50.         break;
  51.         case TCPSOCKET_READABLE: {
  52.             pc.printf("\n\rCan now read some data\r\n");
  53.             if (server_mode) {
  54.                 //Receive command
  55.                 char command[255];
  56.                 int long_command= pClientSock->recv(command, 255);
  57.                 pc.printf("Recibo en el READABLE server: ");
  58.                 for (int i=0;i<long_command;i++) {
  59.                     pc.printf ("%c",command[i]);
  60.  
  61.                 }
  62.                 pc.printf ("\r\n");
  63.                 pc.printf ("\r\nBytes recibidos en el READABLE server: %d", long_command, "\r\n");
  64.                 pc.printf ("\r\nPrimer caracter: %c", command[0], "\r\n");
  65.  
  66.                 if (command[0]=='E') {
  67.                     pc.printf ("\r\nend_NM_config a true\r\n");
  68.                     end_NM_config=true;
  69.                    
  70.                     break;
  71.                 }
  72.  
  73.                 //Process command received
  74.                 pc.printf("Long Received: %d\r\n", long_command);
  75.                 for (int i=0; i<long_command;i++) {
  76.                     pc.printf ("Command Received from PC: %X\n\r",command[i]);
  77.                 }
  78.  
  79.  
  80.                 // simulation of the response of the reader
  81.                 int long_sent=pClientSock->send("Command received OK", sizeof("Command received OK"));
  82.                 pc.printf ("Long sent: %d\r\n", long_sent);
  83.             } else if (client_mode) {
  84.                 char command[255];
  85.                 int long_command= socket.recv(command, 255); //receiving the ACK of the tag
  86.  
  87.                 if (command[0]=='T') {
  88.                  
  89.                     pc.printf ("Va a empezar a enviar tags\r\n");
  90.  
  91.                     int long_sent=socket.send("Tag received", sizeof("Tag received"));
  92.  
  93.  
  94.                 } else if (command[0]=='C') {
  95.  
  96.                     int long_sent=socket.send("Change intention received", sizeof("Change intention received"));
  97.                     change_mode=true;
  98.                    
  99.                     pc.printf("Change mode igual a true\r\n");
  100.                 }
  101.             }
  102.         }
  103.         break;
  104.  
  105.         case TCPSOCKET_DISCONNECTED: {
  106.             pc.printf("\r\nDISCONNECTED...\n\rCLOSING SOCKET\r\n");
  107.             if (end_NM_config==true) {
  108.                 pc.printf("voy a cambiar a cliente en DISCONNECTED\r\n");
  109.                 socket.close();
  110.                 pClientSock->close();
  111.              
  112.                 socket_communication();
  113.                 end_NM_config=false;
  114.             } else if (change_mode) {
  115.                 pc.printf ("voy a cambiar a servidor en el DISCONNECT\r\n");
  116.                 socket.close();
  117.                 socket_event();
  118.                 change_mode=false;
  119.             }
  120.         }
  121.         break;
  122.  
  123.         default: {
  124.             pc.printf("\r\nUNKNOWN EVENT...\r\nCLOSING SOCKET\r\n");
  125.             socket.close();
  126.         }
  127.         break;
  128.     }
  129. }[/CODE]


En los eventos "DISCONNECTED" y "CONRST" es donde realizo el cambio de servidor a cliente y de cliente a servidor.
en el primer caso, cierro socket y pClientSock y llamo a la función "socket_communication" que abre un socket y lo conecta al servidor remoto:

Código C++:
Ver original
  1. [CODE]////////////////////////////////////////////////////////
  2. ///////Function to open a communication socket//////////
  3. ////////////////////////////////////////////////////////
  4.  
  5. int socket_communication() {
  6.     socket.resetOnEvent();
  7.     socket.setOnEvent(&onTCPSocketEvent);
  8.     Host server(IpAddr(134, 96, 214, 35),20001); //READER IP + PORT
  9.     TCPSocketErr bindErr = socket.connect(server);
  10.     if (bindErr) {
  11.         pc.printf("\r\nERROR BINDING server...\r\n");
  12.         return 0;
  13.     }
  14.     pc.printf("\r\nCONNECTING TO %d.%d.%d.%d \n\r", server.getIp()[0], server.getIp()[1], server.getIp()[2], server.getIp()[3]);
  15.     server_mode=false;
  16.     client_mode=true;
  17.     return 0;
  18. }[/CODE]


En el segundo caso, cierro el socket que se utiliza en modo cliente y vuelvo a llamar a "socket_server", donde vuelvo a hacer el bind con la misma IP y puerto.

Sé que es un lio todo este código, pero el problema lo tengo cuando hago el close.socket();
socket_event();
Es como si el close.socket() no cerrase del todo la conexión, o como si , cuando cerré por primera vez los sockets en modo server, se hubiese dejado rastro que no me permite volver a hacer el bind con la misma IP y puerto.
Estoy casi segura de que es lo que dices tú, que aunque cierre la conexión, el socket sigue escuchando, pero cómo puedo hacer para que pare?
Espero que se entienda algo de mi problema
Gracias!

Última edición por mariaamo; 21/06/2011 a las 03:21