Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Debci en 18 Noviembre 2012, 14:05 pm



Título: Incorrecta implementación de Thread?
Publicado por: Debci en 18 Noviembre 2012, 14:05 pm
Hola a todos los foreros, compañero de elhacker.net

Tras mucho tiempo sin hacer nada de C++ me he dispuesto a practicar un poco, con algunos sockets y threads.
El problema es que no estoy muy seguro de como funciona la cosa (que fácil es en Java...).
La idea es un servidor que esta esperando siempre a un cliente para recibir de este, un buffer con una cadena de texto que mostrará por pantalla.
La idea, para probarlo, ha sido que el cliente dentro de un while, y este dentro de la acción que se introduce a thread, se dedique a enviar de forma indefinida una cadena de texto.
Sin mas os dejo el código fuente:

Todo, esta realizado con el IDE codeblocks y el entorno MinGW.

Cliente:
Código
  1. #include <iostream>
  2. #include <windows.h>
  3. #define PUERTO 8080
  4. #include <process.h>
  5. using namespace std;
  6.  
  7. WSADATA wsa;
  8. SOCKET cliente;
  9. sockaddr_in remoto;
  10.  
  11. int error();
  12.  
  13. void Thread( void* pParams )
  14.  {
  15.    if(WSAStartup(MAKEWORD(2,2), &wsa)){
  16.  
  17.    }
  18.    remoto.sin_family = AF_INET;
  19.    remoto.sin_port = htons(PUERTO);                                    // Puerto donde nos conectaremos
  20.    //remoto.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");             // IP del servidor a donde nos conectaremos
  21.    remoto.sin_addr = *((in_addr*)gethostbyname("localhost")->h_addr);  // Host a donde nos conectaremos
  22.    while(1){
  23.    cliente = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);        // Protocolo TCP
  24.    if(cliente == INVALID_SOCKET){
  25.  
  26.    }
  27.    if(connect(cliente, (sockaddr*)&remoto, sizeof(sockaddr))){     // Conectamos con el servidor
  28.  
  29.    }
  30.    string buffer = "Hola, soy un cliente en C++!";
  31.    send(cliente, buffer.c_str(), buffer.length(), 0);                          // Enviamos un saludo
  32.    closesocket(cliente);                                                       // Finalmente desconectamos...
  33.    WSACleanup();
  34.    }
  35.  }
  36.  
  37. int main(){
  38.    _beginthread( Thread, 0, NULL );
  39.  
  40.  
  41.    return 0;
  42. }
  43.  

Servidor:
Código
  1. #include <iostream>
  2. #include <windows.h>
  3. #pragma comment(lib, "Ws2_32.lib")
  4. #define PUERTO 8080
  5. #include <pthread.h>
  6.  
  7. using namespace std;
  8.  
  9. WSADATA wsa;
  10. pthread_t hilo;
  11. SOCKET servidor, nueva_conexion;
  12. sockaddr_in local;
  13.  
  14. int error();
  15.  
  16. int main(){
  17.    local.sin_port = htons(PUERTO);          
  18.    local.sin_family = AF_INET;          
  19.    local.sin_addr.S_un.S_addr = INADDR_ANY;  
  20.  
  21.    if(WSAStartup(MAKEWORD(2,2), &wsa)){
  22.        return error();
  23.    }
  24.    servidor = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  25.    if(servidor == INVALID_SOCKET){
  26.        return error();
  27.    }
  28.    if(bind(servidor, (sockaddr*)&local, sizeof(sockaddr)) == SOCKET_ERROR){
  29.        return error();
  30.    }
  31.  
  32.    if(listen(servidor, 1) == SOCKET_ERROR){    
  33.        return error();
  34.    }
  35.  
  36.    cout << "Servidor a la escucha por el puerto " << PUERTO << ", esperando conexión." << endl;
  37. while(1){
  38.    do{
  39.        nueva_conexion = accept(servidor, NULL, NULL); // Esperamos una conexión entrante y la aceptamos.
  40.    } while(nueva_conexion == SOCKET_ERROR);
  41.  
  42.    string mensaje = "Servidor C++!";
  43.  
  44.    send(nueva_conexion, mensaje.c_str(), mensaje.length(), 0); // Enviamos un mensaje al cliente conectado
  45.  
  46.    int bytes_recv;
  47.    char buffer[256];
  48.  
  49.  
  50.  
  51.        memset(buffer, 0, sizeof(buffer)); // Limpiamos el buffer.
  52.    do{
  53.        bytes_recv = recv(nueva_conexion, buffer, sizeof(buffer), 0);   // Esperamos para recibir datos...
  54.    } while(bytes_recv == 0 && bytes_recv != SOCKET_ERROR);
  55.  
  56.    if(bytes_recv > 0){
  57.        cout << "Buffer: " << buffer << " - Bytes recibidos: " << bytes_recv << endl;
  58.  
  59.    }
  60.  
  61. }
  62.    closesocket(nueva_conexion);                                    // Lo desconectamos!
  63.  
  64.    WSACleanup();
  65.  
  66.    return 0;
  67. }
  68.  
  69. int error(){
  70.    cout << "Error #" << GetLastError() << endl;
  71.    WSACleanup();
  72.  
  73.    return 0;
  74. }
  75.  

El problema aparece, cuando al ejecutar el cliente, este ni siquiera comienza el bucle, es decir, el thread no se inicia o por algún motivo esta mal usada la función.

Gracias por vuestro tiempo.
Un saludo