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]

Connection timed out - socket error crashes my program
briggins5
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
> 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
Marek Istvanek
Maybe the MAQUINA class contains some special members, like std::string. I would suggest revealing it to us.
mcrisf
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:
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:
I hope this helps.
S Lyons
Thanx
Aoeuid
... 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
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;