Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - Chains

#1
Jeje, no, no era de eso (lo había pensado). Acabo ahora mismo de encontrar la solución al problema. Por alguna razón el nombre de mi clase estaba haciendo algún conflicto con algo, y el compilador lo interpretaba como una estructura en vez de una clase.

Me ha bastado con cambiar el nombre de la clase, la he llamado "servman" en vez de "ServerClass", y el compilador ya ha dejado de quejarse. Había probado de todo, menos a cambiar el nombre de la clase.

Gracias por la ayuda, en cualquier caso.
#2
Estoy intentando definir una clase para poder acceder a sus funciones desde otras clases. La clase debería ser estática, es decir, no debe ser instanciada.

Éste es el código de la cabecera (ServerClass.h)

Código (cpp) [Seleccionar]
#define DEFAULT_BUFLEN 512
#ifndef __SERVERCLASS_H__
#define __SERVERCLASS_H__

class ServerClass
{
public:
    static int CreateServer(HWND);
    static int CloseServer();
    char* getcbuffer();
    int listensock();
private:
    SOCKET ListenSocket;
    SOCKET ClientSocket;
    char recvbufx[DEFAULT_BUFLEN];
    int recvbuflen;
};
#endif


El problema es que al compilar, me da dos errores algo extraños en las líneas 6 y 17:

En linea 6: error: an anonymous struct cannot have function members
En linea 17: error: abstract declaratos '<anonymous class>' used as declaration


¿Por qué me detecta la clase como una estructura, si le he añadido la palabra 'class'? Es un proyecto en Code::Blocks para Windows, usando el compilador GNU GCC, y el proyecto es en C++, no en C.
#3
Muchísimas gracias por tu aporte, BlackZeroX. Sinceramente, me es de gran ayuda. Pero hay una cosa que no me explico.

He logrado pasar de la linea erronea, pero ahora el error me lo produce en la función "connect".

Código (cpp) [Seleccionar]
connect(sock, (SOCKADDR *)&remoto, sizeof (remoto));

Pero lo mejor, es que he descubierto, que la línea que antes no me funcionaba, en éste programa me deja de funcionar si declaro "hostent * direc" fuera de la función main.

Es decir, que si hago ésto

Código (cpp) [Seleccionar]
int main()
{
    hostname = new char[1024];
    hostent * direc = NULL;
/* ... */
    remoto.sin_addr = *((struct in_addr *)direc->h_addr);
/* ... */
}


El programa no me devuelve error en esa línea. Pero si hago ésto

Código (cpp) [Seleccionar]

hostent * direc = NULL;

int main()
{
    hostname = new char[1024];
/* ... */
    remoto.sin_addr = *((struct in_addr *)direc->h_addr);
/* ... */
}


Al llegar a esa línea, da error de violación de acceso. Ésto es algo que no logro comprender, y que tiene algo que ver seguro con la gestión de la memoria, pero no sé si es error mio, del compilador, del ordenador... no logro entender nada y mi cabeza hecha chíspas.

He probado a meter el programa en Dev-C++, pero me da error en todas las funciones de la librería winsock (aunque no me da error al importarla en la cabecera). No sé si es que tal vez debería añadir algún parametro especial en las opciones del enlazador. Lo mísmo pasa si en Code::Blocks cambio el compilador al LCC, que me lo bajé para probar a ver si funcionaba bien así, sólo que en éste caso me da error en todas las líneas. Es un verdadero caos.
#4
Si, estoy realizando un programa de consola en Windows. Uso el entorno de desarrollo Code::Blocks, y de compilador el GNU GCC Compiler, que viene por defecto con éste entorno de desarrollo. El código, por cierto, lo saqué de ésta página: http://www.nullterminator.net/winsock.html, y sólo le realicé algunas modificaciones al código del servidor, porque me daba algunos errores y también para ajustarlo a mis necesidades.

He probado a inicializar winsock en el programa cliente usando el siguiente código:

Código (cpp) [Seleccionar]
WSADATA wsaData;
    WORD version;
    int error;

    version = MAKEWORD( 2, 0 );

    error = WSAStartup( version, &wsaData );

    /* check for error */
    if ( error != 0 )
    {
    /* error occured */
        return FALSE;
    }

    /* check for correct version */
    if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 0 )
    {
    /* incorrect WinSock version */
        printf("\n\nError 01: Incorrect WinSock Version. LOBYTE: %n . HIBYTE: %n .", (INT*)LOBYTE( wsaData.wVersion ), (INT*)HIBYTE( wsaData.wVersion ));
        WSACleanup();
        return FALSE;
    }

    client = socket( AF_INET, SOCK_STREAM, 0 );

/* Resto del progrma */


También he añadido las correspondientes líneas al final del código para cerrar el socket, pero sigo recibiendo el mísmo error al llegar a la mísma línea.



A continuación dejo el código entero del cliente con las modificaciones realizadas:

Código (cpp) [Seleccionar]
/* CLIENT */
#define __rtems__
#include <windows.h>
#include <winsock2.h>
#include <stdio.h>
//#include <pthread.h> //Es para crear POSIX threads, lo necesitaré más tarde
#include <conio.h>
#include <iostream>
#include <conio.h>
#include <fstream>

SOCKET client;
struct hostent * host;
char* hostname;

int main()
{
    hostname = new char[1024];
    WSADATA wsaData;
    WORD version;
    int error;

    version = MAKEWORD( 2, 0 );

    error = WSAStartup( version, &wsaData );

    /* check for error */
    if ( error != 0 )
    {
    /* error occured */
        return FALSE;
    }

    /* check for correct version */
    if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 0 )
    {
    /* incorrect WinSock version */
        printf("\n\nError 01: Incorrect WinSock Version. LOBYTE: %n . HIBYTE: %n .", (INT*)LOBYTE( wsaData.wVersion ), (INT*)HIBYTE( wsaData.wVersion ));
        WSACleanup();
        return FALSE;
    }

    client = socket( AF_INET, SOCK_STREAM, 0 );

    printf("Please enter the IP or name of the host to join> ");
    fflush( stdout );
    scanf("%s", hostname);
    printf("\n\nAttempting connection with host %s", hostname);
    host = gethostbyname( hostname );
    //printf("\n%p", host); //DEBUG
    struct sockaddr_in sin;

    memset( &sin, 0, sizeof sin );
    //printf("\nSuccess0"); //DEBUG
    sin.sin_family = AF_INET;
    //printf("\nSuccess1"); //DEBUG
    sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
    //printf("\nSuccess2"); //DEBUG, el programa se traba aqui
    sin.sin_port = htons( 21 );
   
    if ( connect( client, (PSOCKADDR)&sin, sizeof sin ) == SOCKET_ERROR )
    {
        printf("\n\nError 01: Could not connect to the defined host: %s.", hostname);
        return FALSE;
    }
   
    WSACleanup();
    closesocket( client );
    return 0;
}
#5
Entiendo. Ahora mi pregunta es, si no puedo acceder a host porque es un puntero no válido, ¿Qué tengo que hacer entonces para obtener la dirección del servidor a partir del nombre del host especificado, sin usar la estructura hostent?

Siento ser tan persistente, pero como ya he dicho, aunque tengo nociones de lo que estoy haciendo, no estoy muy experimentado en C++, y no estoy demasiado acostumbrado a todos estos temas de punteros y sockets. Intento sacar la mayor información que puedo de internet, pero no encuentro la suficiente. El código de mi programa, es sacado también de una página, y ya he tenido que resolver un sinfín de errores. No lo entiendo...
#6
Ah, de acuerdo, no sabía a lo que te referías con el valor de gethostbyname. Lo he estado comprobando y devuelve 0.
#7
gethostbyname es una estructura tipo hostent . Pero he descubierto que si intento obtener el valor de h_addr de la variable host (la que contiene el valor de retorno de gethostbyname()), me da el error de violación de acceso, así que el error o está en h_addr_list, o en h_addr, o peor aún en la estructura host.

Me da error igual tanto si intento obtenerlo mediante h_addr, como por h_addr_list[0]. También he intentado definir h_addr como una variable independiente en la estructura en lugar de asignarle una región de h_addr_list, pero tampoco ha funcionado.
#8
Pues poca cosa he podido sacar. He estado comprobando las estructuras, pero no veo nada raro.

La estructura de hostent es:

struct  hostent {
char *h_name;
char **h_aliases;
short h_addrtype;
short h_length;
char **h_addr_list;
#define h_addr h_addr_list[0]
};


Y la del in_addr:

struct in_addr {
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;


Ambas pertenecen a la cabecera winsock2.h

Empiezo a sospechar que el error pudiera venir de antes, concretamente de ésta línea:

memset( &sin, 0, sizeof sin );

Como aloja sin en la memoria, tal vez por algún motivo el puntero se salga de la región de sin y apunte a otro lado que no debe, y de ahí el error. No estoy muy seguro.
#9
Buenos días. Estoy tratando de crear un pequeño programa cliente-servidor usando C++. He de admitir que soy un poco nuevo en esto de C++ y sobre todo en el uso de sockets (soy programador de C#).

Bien, la cuestión es que mi programa produce un error de violación de acceso (0xC0000005) al ejecutar una de sus lineas. Éste es el programa en cuestión (Es el cliente):

SOCKET client;
struct hostent * host;
char* hostname;

int main()
{
    hostname = new char[1024];
    client = socket( AF_INET, SOCK_STREAM, 0 );
    printf("Please enter the IP or name of the host to join> ");
    fflush( stdout );
    scanf("%s", hostname);
    printf("\n\nAttempting connection with host %s", hostname);
    host = gethostbyname( hostname );
    struct sockaddr_in sin;

    memset( &sin, 0, sizeof sin );

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;
    sin.sin_port = htons( 21 );
    if ( connect( client, (PSOCKADDR)&sin, sizeof sin ) == SOCKET_ERROR )
    {
    printf("Error 01: Could not connect to the defined host: %s.", hostname);
    return FALSE;
    }
    closesocket( client );
    return 0;
}


El error en cuestión me lo produce al ejecutar la siguiente línea:

sin.sin_addr.s_addr = ((struct in_addr *)(host->h_addr))->s_addr;

Y no sé que hacer para solucionarlo, pues apenas hay documentación en internet acerca del uso de sockets en C++. Les agradecería que me guiaran un poco en mi tarea. Muchas gracias.