Re: Program crashes when trying to connect Glib::signal_io



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Lucky Luke wrote:
> 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
> <mailto: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
> <mailto: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. :)

You are trying to watch an IO channel that you have not yet created. I
think you should do that at the end of your connect() function. Also
note that on Windows, you should use
Glib::IOChannel::create_from_win32_socket rather than create_from_fd.

Armin

> -- 
> Lucas
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> gtkmm-list mailing list
> gtkmm-list gnome org
> http://mail.gnome.org/mailman/listinfo/gtkmm-list

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGIfr3hOtxKlDYm6cRAobPAJ0Vdie0XcY9WSaoNelvhKPfE+xAmgCeM+im
BfFi/WOm3R7dJ8O2BeebmvA=
=c8H8
-----END PGP SIGNATURE-----



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]