Program crashes when trying to connect Glib::signal_io
- From: "Lucky Luke" <luckyluke56 gmail com>
- To: gtkmm-list gnome org
- Subject: Program crashes when trying to connect Glib::signal_io
- Date: Sun, 15 Apr 2007 11:41:37 +0200
Hi,
I have a Socket class, which connects the Glib::signal_io signal. But when I run the project, it crashes, with no other information. I'm currently on windows, and I read that Glib uses the select() and poll() functions to determine which socket to read. But when I look at the winsock functions reference, I see no poll() function. Could that be the problem?
Here's my code:
#
#-----[ socket.h ]---------------------------------------------------------------
#
/**
* Lucky Bot C++ Version 1.0
* An extendable IRC Bot written in C++
*
* Copyright 2007 by Lucas van Dijk (
info lucasvd nl)
*
http://www.lucasvd.nl *
* @author Lucas van Dijk
* @license
http://www.opensource.org/osi3.0/licenses/gpl-license.php *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef SOCKET_H_INCLUDED
#define SOCKET_H_INCLUDED
#ifdef WIN32
#include <winsock.h
>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif // ifdef WIN32
#include "../../stdinc.h"
namespace LuckyBot { namespace Sockets
{
/**
* This is our main Socket class
* It uses the GTKmm IO monitoring functions, so it's non blocking.
*/
class Socket
{
// Members
protected:
/// Keeps track of the number of sockets open
static int num_sockets;
/// Holds the socket file descriptor
int socket;
/// This is a Glib::iochannel which is used for non blocking I/O
Glib::RefPtr<Glib::IOChannel> iochannel;
/// Holds address info
sockaddr_in address;
virtual bool OnIOCallback(Glib::IOCondition condition) = 0;
// Methods
public:
Socket();
virtual ~Socket();
virtual bool connect(Glib::ustring hostname, int port);
virtual void send(Glib::ustring message);
virtual Glib::ustring receive(int length = -1);
};
}
}
#endif // SOCKET_H_INCLUDED
#
#-----[ socket.cpp ]------------------------------------------------------------------------------
#
/**
* Lucky Bot C++ Version 1.0
* An extendable IRC Bot written in C++
*
* Copyright 2007 by Lucas van Dijk (
info lucasvd nl)
*
http://www.lucasvd.nl *
* @author Lucas van Dijk
* @license
http://www.opensource.org/osi3.0/licenses/gpl-license.php *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "socket.h
"
int LuckyBot::Sockets::Socket::num_sockets = 0;
namespace LuckyBot { namespace Sockets
{
/**
* Constructor, initializes the socket
* If we're on windows, the WSAData struct will be automaticly initialized,
* then a new socket file descriptor is created
*/
Socket::Socket()
{
std::cout << "Number of sockets before: " << num_sockets << std::endl;
// If we're on windows, we need to initialize the wsa
#ifdef WIN32
// We need to initialize it only once
if(num_sockets == 0)
{
std::cout << "Initializing WSA" << std::endl;
WSADATA wsa_data;
if (WSAStartup(MAKEWORD(1, 1), &wsa_data) != 0)
{
std::cout << "WSA Startup failed" << std::endl;
exit(1);
}
}
#endif // WIN32
// Initialize socket
this -> socket = ::socket(PF_INET, SOCK_STREAM, 0);
char yes = '1';
if (setsockopt(this -> socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1)
{
std::cout << "Could not set socket option" << std::endl;
Gtk::Main::quit();
}
this -> address.sin_family = AF_INET;
memset(&(this ->
address.sin_zero), '\0', 8);
// Increment number of sockets
num_sockets++;
std::cout << "Number of sockets after: " << num_sockets << std::endl;
// Connect to Glib IO Signal
Glib::signal_io().connect(sigc::mem_fun(*this, &Socket::OnIOCallback), this -> iochannel, Glib::IO_IN);
}
/**
* Connect to the given adress.
* Does nothing special except using the connect() function to connect to the socket
* @return true on success, else false
*/
bool Socket::connect(Glib::ustring hostname, int port)
{
// Resolve DNS
hostent * host = gethostbyname(hostname.c_str());
if(host == 0)
{
std::cout << "Could not resolve DNS: " << hostname.c_str() << " Error code: " << h_errno << std::endl;
throw std::runtime_error("Could not resolve DNS");
}
// Copy address
memcpy(&this -> address.sin_addr, host->h_addr_list[0], host->h_length);
this -> address.sin_port = htons(port);
// Let's connect to the adress
int result = ::connect(this -> socket, (sockaddr *) &(this -> address), sizeof(sockaddr));
if(result == -1)
{
std::cout << "Could not connect" << std::endl;
return false;
}
else
{
// Initialize IOChannel object
this -> iochannel = Glib::IOChannel::create_from_fd(this -> socket);
return true;
}
}
/**
* Sends a given string to the socket
* @param message The message to send
* @return Number of bytes actually sent
*/
void Socket::send(Glib::ustring message)
{
this -> iochannel -> write(message);
}
/**
* Receives data from the socket
* @param buffer the buffer for the contents
* @param the max number of bytes to receive
* @return The message received
*/
Glib::ustring Socket::receive(int length)
{
Glib::ustring buffer;
if(length == -1)
{
// reads a line
this -> iochannel -> read_line(buffer);
}
else
{
this -> iochannel -> read(buffer, length);
}
return buffer;
}
/**
* Destructor, closes the socket
* If this is the last open socket, and we're on windows, the WSAData struct is also automaticly cleaned up
*/
Socket::~Socket()
{
// Decrement the number of sockets
num_sockets--;
::shutdown(this -> socket, 2);
// Clean up WSA
#ifdef WIN32
if(num_sockets == 0)
{
WSACleanup();
}
#endif // WIN32
}
}
}
Thanks in advance. :)
--
Lucas
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]