Connection timed out - socket error crashes my program

Hello forum,
I'm desperate. I made a class in a client application, which has a function that loops through a series of hosts. However, when it finds a "connection timed out" error, it simply crashes with "std::out_of_range memory location" - when I just want it to go on without connecting to that server. It only breaks after the 2nd iteration - the first goes by smoothly, the 2nd crashes. What can I do

[code]
void Escalonador::Conecta(char* endereco){
MAQUINA temp;
// variaveis de socket.
WSADATA ws;
int err; // verifica erros
hostent *host; // dados do servidor
SOCKET s; // descritor de socket
SOCKADDR_IN addr; // endereco IP do host

// testa a DLL associada a socket (WS2_32.DLL)
cout << "Inicializando DLL... ";
err = WSAStartup(MAKEWORD(2,0),&ws);
if(err != 0){
cout << "Nao foi possivel inicializar a DLL de socket!" << endl;
WSACleanup();

}
// a DLL existe; testa a versao de socket a ser usada. Pedimos 2.0.
if(LOBYTE(ws.wVersion) != 2 || HIBYTE(ws.wVersion) != 0){
cout << "Versao 2.0 de socket nao suportada!" << endl;
WSACleanup();
}
cout << "OK" << endl;
// teste executado; cria um socket
cout << "Criando novo socket... ";
s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(s == SOCKET_ERROR){
cout << "Nao foi possivel inicializar o socket!" << endl;
closesocket(s);
WSACleanup();
}
cout << "OK" << endl;
// configura o host a ser usado
cout << "Configurando informacoes de host... ";
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(endereco);
if(addr.sin_addr.s_addr == INADDR_NONE){
// nao e endereco ip; resolve o endereco a partir de DNS
host = NULL;
host = gethostbyname(endereco);
if(host == NULL){
cout << "Host desconhecido!" << endl;
closesocket(s);
WSACleanup();
}
memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
}
cout << "OK" << endl;
// conecta ao host
cout << "Conectando em " << endereco << ":" << port << "...";
err = connect(s, (sockaddr *)&addr, sizeof(addr));
if(err == SOCKET_ERROR){
cout << "Nao foi possivel estabelecer a conexao!" << GetLastError() << endl;
closesocket(s);
WSACleanup();
}
cout << "OK" << endl;
// envia dados ao host
cout << "Enviando dados a " << endereco << "... ";
err = send(s, (char*)&temp, sizeof(temp), 0);
if(err == SOCKET_ERROR){
cout << "Nao foi possivel enviar os dados!" << endl;
closesocket(s);
WSACleanup();
}
cout << "OK" << endl;
// recebe resposta do host
cout << "Recebendo resposta de " << endereco << "... ";
err = recv(s, (char*)&temp, sizeof(temp), 0);
while(err != SOCKET_ERROR){
err = recv(s, (char*)&temp, sizeof(temp), 0);
if (err == 0){
cout << "OK" << endl;
break;
}
}
if(err == SOCKET_ERROR){
cout << "Nao foi possivel receber todos os dados!" << endl;
}
// adiciona ao vetor "windows"
cout << "Recebido!" << endl;
windows.push_back(temp);
// finaliza conexao
cout << "Finalizando conexoes... ";
closesocket(s);
WSACleanup();
cout << "OK" << endl;
}
[/code]


Answer this question

Connection timed out - socket error crashes my program

  • briggins5

    I did, it kept crashing.
    It says something about std::out_of_range at memory location (hexadecimal number).
    Compiling the same code in Linux, with g++ (properly adapted, naturally) it gives me a segmentation error.

    If it helps in anything, when I look under the tab 'locals' it shows:
    this    <Bad Ptr>    std::basic_string<char,std::char_traits<char>,std::allocator<char> > * const

    and

    +        _Right    "invalid vector<T> subscript"    const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &


    And here's my stack:

    >    sleip-client.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::assign(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right="invalid vector<T> subscript", unsigned int _Roff=0x00000000, unsigned int _Count=0xffffffff)  Line 1014    C++
         sleip-client.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> >(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & _Right=<Bad Ptr>)  Line 597    C++
         0012f884()   
         sleip-client.exe!std::vector<maquina,std::allocator<maquina> >::_Xran()  Line 1219 + 0x2e bytes    C++
         sleip-client.exe!std::vector<maquina,std::allocator<maquina> >::at(unsigned int _Pos=0x00000000)  Line 732    C++
         sleip-client.exe!Escalonador::Escalona()  Line 274 + 0xc bytes    C++
         sleip-client.exe!Escalonador::iEscalonador()  Line 284    C++
         sleip-client.exe!main(int argc=0x00000003, char * * argv=0x003534c0)  Line 34    C++
         sleip-client.exe!__tmainCRTStartup()  Line 318 + 0x12 bytes    C


  • AlexBB

    Here's what the Visual Studio debugger says:
    > sleip-client.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Eos(unsigned int _Newsize=1243568) Line 1994 + 0xa bytes C++


  • Rashar

    That's the problem... except for character pointers, I'm not using any - at least I don't think I am...

  • Marek Istvanek

    Maybe the MAQUINA class contains some special members, like std::string. I would suggest revealing it to us.


  • mcrisf

    Revised code, same problem (by the way; if it succeeds in connecting for the first iteration, it crashes even before beginning the 2nd, right after "finalizando conexoes". If it doesn't succeed making the 1st connection, it crashes right after "Nao foi possivel estabelecer conexao!". Both cases it crashes with std::out_of_range memory [location] ):

    void Escalonador::Conecta(){
    MAQUINA temp;
    // variaveis de socket.
    try{
    char buffer[128];
    ifstream hosts("..\\configuration\\hosts.conf");
    if(hosts.fail()){
    free(buffer);
    throw "Nao foi possivel abrir o arquivo de hosts!";
    }
    // recebe dados de todos os hosts disponiveis
    while(hosts.get(buffer,sizeof(buffer),'\n')){

    WSADATA ws;
    int err; // verifica erros
    hostent *host = NULL; // dados do servidor
    SOCKET s; // descritor de socket
    SOCKADDR_IN addr; // endereco IP do host

    // testa a DLL associada a socket (WS2_32.DLL)
    cout << "Inicializando DLL... ";
    err = WSAStartup(MAKEWORD(1,1),&ws);
    if(err != 0){
    free(buffer);
    throw "Nao foi possivel inicializar a DLL de socket!";
    }

    // a DLL existe; testa a versao de socket a ser usada. Pedimos 1.1.
    if(LOBYTE(ws.wVersion) != 1 || HIBYTE(ws.wVersion) != 1){
    free(buffer);
    throw "Versao 2.0 de socket nao suportada!";
    }
    cout << "OK" << endl;

    // teste executado; cria um socket
    cout << "Criando novo socket... ";
    s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
    if(s == SOCKET_ERROR){
    cerr << "Nao foi possivel inicializar o socket!" << endl;
    continue;
    }
    cout << "OK" << endl;
    // configura o host a ser usado
    cout << "Configurando informacoes de host... ";
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(buffer);
    if(addr.sin_addr.s_addr == INADDR_NONE){
    // nao e endereco ip; resolve o endereco a partir de DNS
    host = gethostbyname(buffer);
    if(host == NULL){
    cerr << "Host desconhecido!" << endl;
    continue;
    }
    memcpy(&addr.sin_addr, host->h_addr_list[0], host->h_length);
    }
    cout << "OK" << endl;

    // conecta ao host
    cout << "Conectando em " << buffer << ":" << port << "...";
    err = connect(s, (sockaddr *)&addr, sizeof(addr));
    if(err == SOCKET_ERROR){
    cerr << "Nao foi possivel estabelecer a conexao!" << endl;
    continue;
    }
    cout << "OK" << endl;
    // envia dados ao host
    cout << "Enviando dados a " << buffer << "... ";
    err = send(s, (char*)&temp, sizeof(temp), 0);
    if(err == SOCKET_ERROR){
    cerr << "Nao foi possivel enviar os dados!" << endl;
    continue;
    }
    cout << "OK" << endl;

    // recebe resposta do host
    cout << "Recebendo resposta de " << buffer << "... ";
    err = recv(s, (char*)&temp, sizeof(temp), 0);
    while(err != SOCKET_ERROR){
    err = recv(s, (char*)&temp, sizeof(temp), 0);
    if (err == 0){
    cout << "OK" << endl;
    break;
    }
    }
    if(err == SOCKET_ERROR){
    cerr << "Nao foi possivel receber todos os dados!" << endl;
    continue;
    }
    // adiciona ao vetor "windows"
    cout << "Recebido!" << endl;
    windows.push_back(temp);
    // finaliza conexao
    cout << "Finalizando conexoes... ";
    closesocket(s);
    WSACleanup();
    cout << "OK" << endl;
    }
    hosts.close();
    }catch(const char* str){
    cerr << "Erro! " << str << endl;
    WSACleanup();
    }
    }

  • Daniel Hardjosuwito

    I think it is not good to send and receive members of type std::string in your manner. It may work for short endereco and sistema values, but if they are longer, they are allocated dynamically. The internal hidden pointers of std::strings cannot be transferred directly.

    Maybe you can change the definition to fixed-size strings:

    typedef struct maquina {

    . . .

    char endereco[20];

    char sistema[20];

    . . .

    } MAQUINA;

    In this case there are no problematic pointers in your structure.


  • vannielou

    I think you should add return instructions in case of errors (after each WSACleanup).

    For instance:

    if( host == NULL)

    {

    cout << "Host desconhecido!" << endl;

    closesocket(s);

    WSACleanup();

    return;

    }

    I hope this helps.


  • S Lyons

    if you Are using Pointer in your Function just Check it Out .I Don't think That you are properly allocating memory to your pointer and After Finish Them Don't Forget Them .if you Want Declare at once and also free at Once So Simply use First time to Allocate memory and Delete to Free the memory Remaining time you can use memset to Initialize your Pointer.Apart from this I Don't think There can be Any Error.


    Thanx


  • Aoeuid

    Thanks for the tip; maybe that's what messing with my system. Compiling in Linux still gives me a segmentation fault, probably due to that. Let's see if I fix it...

    ... ok, I think I definately solved it. Fixed the string thing (changed it to char[]), then I fixed the initialization thing. Then it was crashing when it came to the last line without making any connections.

    There was a line where I told the system to erase elements that did not conform to the user's requirements (that is, where sistema != user_choice), and that was crashing it. Fixed that and now, it crashes no more (I seriously hope).

  • Nishant Sivakumar

    ... actually, I just solved it (I think). The problem was with the vector initialization - the Escalonador class has a member called 'vector<MAQUINA> windows'. I added a 'dummy' MAQUINA object to the constructor and at least it isn't crashing at random when I debug. Let's see if it does work with more than one connection.

    Yes, the MAQUINA type does have a string member - here's its definition:


    typedef struct maquina{
    long carga;
    long mem_livre;
    long mem_total;
    float clock;
    string endereco;
    string sistema;
    int peso;
    } MAQUINA;

  • Connection timed out - socket error crashes my program