Need Help with ENet.

Started by
5 comments, last by windshadow 15 years, 8 months ago
I'm trying to make an IRC bot in C++ (As a networking test) But I've got a bit of trouble. Here's my code:
#include "CIRCCon.h"

using namespace std;

ENetHost * client;
ENetAddress address;
ENetEvent event;
ENetPeer *peer;

int cLen=0;

CIRCCon::CIRCCon()
{
	if (enet_initialize () != 0)
	{
		fprintf (stderr, "An error occurred while initializing ENet.\n");
	}
}

// Good Programmer don't comment this
CIRCCon::~CIRCCon(){ enet_deinitialize();}

void CIRCCon::connectServer(char* ip,int port)
{
    client = enet_host_create (NULL /* create a client host */,
                1 /* only allow 1 outgoing connection */,
                57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
                14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);

    if (client == NULL)
    {
        fprintf (stderr, 
                 "An error occurred while trying to create an ENet client host.\n");
        exit (EXIT_FAILURE);
    }

	/* Connect to some.server.net:1234. */
	enet_address_set_host (& address, ip);
	address.port = port;

	/* Initiate the connection, allocating the two channels 0 and 1. */
	peer = enet_host_connect (client, & address, 2);    

	if (peer == NULL)
	{
		fprintf (stderr, 
			"No available peers for initiating an ENet connection.\n");
		exit (EXIT_FAILURE);
	}

	/* Wait up to 5 seconds for the connection attempt to succeed. */
	if (enet_host_service (client, & event, 10000) > 0 &&
		event.type == ENET_EVENT_TYPE_CONNECT)
	{
		printf("Connected to %s:%d\n",ip,port);
	}
	else
	{
		/* Either the 5 seconds are up or a disconnect event was */
		/* received. Reset the peer in the event the 5 seconds   */
		/* had run out without any significant event.            */
		enet_peer_reset (peer);

		printf("Connection to %s:%d failed\n",ip,port);
	}

}


void CIRCCon::startServer(int port)
{
	// Connect to a server.
	/*	con.sin_family = AF_INET;
	con.sin_addr.s_addr = inet_addr( "0.0.0.0" );
	con.sin_port = htons( port );

	if ( bind( m_socket, (SOCKADDR*) &con, sizeof(con) ) == SOCKET_ERROR) {
	printf( "Failed to connect.\n" );
	WSACleanup();
	return;
	}

	// Listen on the socket.
	if ( listen( m_socket, 1 ) == SOCKET_ERROR )
	printf( "Error listening on socket.\n");
	*/
}

void CIRCCon::waitForClient()
{
}

int CIRCCon::sendData(string data)
{
	/* Create a reliable packet of size 7 containing "packet\0" */
	ENetPacket * packet = enet_packet_create (data.c_str(), 
                                              strlen (data.c_str()) + 1, 
                                              ENET_PACKET_FLAG_RELIABLE);

    /* Send the packet to the peer over channel id 0. */
    /* One could also broadcast the packet by         */
    /* enet_host_broadcast (host, 0, packet);         */
    enet_peer_send (peer, 0, packet);
    /* One could just use enet_host_service() instead. */
    enet_host_flush (client);
	
	printf("[SND] %s\n",data.c_str());

	return 0;
}

void CIRCCon::ilisten()
{
	ENetEvent event;

	/* Wait up to 1000 milliseconds for an event. */
	while (enet_host_service (client, & event, 1000) > 0)
	{
		switch (event.type)
		{
		case ENET_EVENT_TYPE_RECEIVE:
			printf ("A packet of length %u containing %s was received from %s on channel %u.\n",
				event.packet -> dataLength,
				event.packet -> data,
				event.peer -> data,
				event.channelID);

			/* Clean up the packet now that we're done using it. */
			enet_packet_destroy (event.packet);

			break;
		}
	}

}

int CIRCCon::recvData(char *recvbuf,int size)
{
	return 0;
}


void CIRCCon::closeConnection()
{
	enet_host_destroy(client);
}

And here's my init code: void runclient(char *ip, char *fpath) { // Connect To Server w.connectServer(ip,6667); printf("Connected to server...\n"); // Sending File w.sendData("PASS NOPASS\n\r"); //Sends the password not needed for most servers w.sendData("NICK SBot\n\r"); //sends the nickname w.sendData("USER SBot USING PHP IRC\n\r"); //sends the user must have 4 paramters w.sendData("JOIN #test\n\r"); w.ilisten(); // Send Close Connection Signal //w.sendData("QUIT BYE"); printf("Connection ended......\n"); } I'm getting this output in my console:
Quote:Connection to 127.0.0.1:6667 failed Connected to server... [SND] PASS NOPASS [SND] NICK SBot [SND] USER SBot USING PHP IRC [SND] JOIN #test Connection ended......
Can anyone help? :| Edit: make a scrolling box with [ source ] tags. [Edited by - hplus0603 on August 12, 2008 2:16:25 AM]
Advertisement
I haven't studied your code in depth, but it seems to me that 1 second is a pretty short timeout for the initial response. That timeout should probably be in a while loop, and you only exit after it has been inactive for +/- 10 cycles.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

Quote:Original post by swiftcoder
I haven't studied your code in depth, but it seems to me that 1 second is a pretty short timeout for the initial response. That timeout should probably be in a while loop, and you only exit after it has been inactive for +/- 10 cycles.


I changed the time to 10000Ms (10s) and it still fails. :( I'll try making it retry 3 times..

Didn't help
Well, the issue here is you need to take a look at the IRC protocol. You forgot the PING PONG, google it up. Basically, they server will send you PING and when you receive it you must send PONG, so you stay connected.
Quote:Original post by hamik112
Well, the issue here is you need to take a look at the IRC protocol. You forgot the PING PONG, google it up. Basically, they server will send you PING and when you receive it you must send PONG, so you stay connected.


No, I can't even open a connection to the server, it fails here:
		if (enet_host_service (client, & event, 5000) > 0 &&			event.type == ENET_EVENT_TYPE_CONNECT)		{			printf("Connected to %s:%d\n",ip,port);		}		else		{			/* Either the 5 seconds are up or a disconnect event was */			/* received. Reset the peer in the event the 5 seconds   */			/* had run out without any significant event.            */			enet_peer_reset (peer);			printf("Connection to %s:%d failed\n",ip,port);		}
Have you checked your irc server is up and running correctly?
I'm pretty sure that ENet use it's own custom protocol layered on top of UDP. IRC is a TCP based text protocol.

ENet clients can only connect to other ENet servers, and so ENet is the wrong library to use for connecting to an IRC server. ENet is designed to be used for high performance games(and from what I hear is one of the best in it's class).

I think that ENet might also have some simple TCP wrapper functions that you may be able to use, but you are probably better off using raw sockets, or some other networking library.


Here is a really cool article about writing an IRC bot using the Haskell language, which turns out to be a great language for this kind of stuff, since Haskell has great networking support in its standard library, and the language itself deals really well with things like parsing text commands:

http://haskell.org/haskellwiki/Roll_your_own_IRC_bot

This topic is closed to new replies.

Advertisement