I'm relatively new to C++ - I usually use Perl, then dabbled in some Java, and have been teaching myself C++ for the past week or so.
I'm trying to make a class that connects to a simple chat room that uses a simple but proprietary protocol, called CyanChat -
I figured I'll program this to take a step away from all the "tutorial programs" and build something practical, and learn more in the process. I've implemented a CyanChat client library in Perl and in Java (here's the Java version for reference:
The problem I'm running into is that the class needs a socket object of some sort as a class-level private variable, so it needs to be available across multiple class functions (namely, a connect() function, a send(), receive(), and disconnect()). I've tried a couple different socket classes with not much success.
I've tried: Rude Sockets, the GPL "C++ Sockets Library", and a "hand-rolled" sockets class I got from a different site.
Here is the code I have so far:
CCBot.cpp - An implementation of my class
CyanChat.h - Class descriptor for CyanChat class
CyanChat.cpp - Implementation of my class
The problem is in CyanChat.h, at the "ClientSocket socket" line. ClientSocket (the socket code I tried last, which I got from here: has a constructor that wants to be initialized with a host and port. So using a simple "ClientSocket socket" here throws an error when I compile it:
If I comment the line out, as I did in the code here, the error goes away.
The idea is that the "socket" variable be a class-level variable of a ClientSocket type, but it shouldn't be initialized until connect() is called.
I've also tried using Rude Socket, with less success. The one example on this page: has them creating it as a regular object (rude::Socket socket), but then all of the examples in the API reference use a dynamic pointer (Socket *socket = new Socket).
If I adjust my code so that the socket is declared in the header file as "rude::Socket socket;", it throws this error:
If I change the declaration to use *socket like a pointer it will compile with no errors. But if I try to initialize it in connect(), i.e.
So, how can I resolve this? If I can't declare a variable of type ClientSocket, is there a way for connect() to somehow "export" its own ClientSocket variable up to the class level, so that other functions I add later like send() can access it?
Thanks in advance.
Cuvou.com | My personal homepage
I'm trying to make a class that connects to a simple chat room that uses a simple but proprietary protocol, called CyanChat -
I figured I'll program this to take a step away from all the "tutorial programs" and build something practical, and learn more in the process. I've implemented a CyanChat client library in Perl and in Java (here's the Java version for reference:
The problem I'm running into is that the class needs a socket object of some sort as a class-level private variable, so it needs to be available across multiple class functions (namely, a connect() function, a send(), receive(), and disconnect()). I've tried a couple different socket classes with not much success.
I've tried: Rude Sockets, the GPL "C++ Sockets Library", and a "hand-rolled" sockets class I got from a different site.
Here is the code I have so far:
CCBot.cpp - An implementation of my class
Code:
#include <iostream>
#include "CyanChat.h"
int main()
{
using namespace std;
cout << "CyanChat Bot Initializing" << endl;
// Initialize a CC object
CyanChat cho ("cho.cyan.com", 1813);
cho.setDebug(true);
// Show the config
cho.showConfig();
// Connect
cho.connect();
}
CyanChat.h - Class descriptor for CyanChat class
Code:
#ifndef CYANCHAT_H
#define CYANCHAT_H
#include "ClientSocket.h"
#include "SocketException.h"
class CyanChat
{
// Private variables
char host[255];
unsigned int port;
bool connected;
bool loggedin;
bool debugMode;
char nick[20];
// ClientSocket socket;
// Private functions
void init();
void debug(const char *line);
public:
//////////////////
// Constructors //
//////////////////
CyanChat();
CyanChat(const char *host);
CyanChat(unsigned int port);
CyanChat(const char *host,unsigned int port);
///////////////////
// Configuration //
///////////////////
void setDebug(bool setting);
bool getDebug();
void setHost(const char *host);
void setPort(unsigned int port);
void showConfig();
////////////////////
// Public Methods //
////////////////////
void connect();
};
#endif
CyanChat.cpp - Implementation of my class
Code:
#include <iostream>
#include <cstring> // for strncpy
#include <assert.h>
#include "CyanChat.h"
// RudeSocket
#include "ClientSocket.h"
#include "SocketException.h"
/******************************************************************************
* Object Constructors *
******************************************************************************/
CyanChat::CyanChat()
{
// Set the default settings
init();
setHost("cho.cyan.com");
setPort(1812);
}
CyanChat::CyanChat(const char *host,unsigned int port)
{
// Set the hostname AND port
init();
setHost(host);
setPort(port);
}
CyanChat::CyanChat(const char *host)
{
// Set just the hostname
init();
setHost(host);
}
CyanChat::CyanChat(unsigned int port)
{
// Set just the port
init();
setPort(port);
}
void CyanChat::init()
{
// Initialize everything
connected = false;
loggedin = false;
debugMode = false;
}
void CyanChat::debug(const char *line)
{
using namespace std;
if (debugMode)
{
char debug[255];
strncpy(debug, line, 255);
cout << debug << endl;
}
}
/******************************************************************************
* Configuration *
******************************************************************************/
void CyanChat::setDebug(bool setting)
{
debugMode = setting;
}
bool CyanChat::getDebug()
{
return debugMode;
}
void CyanChat::setHost(const char *host)
{
debug("Setting hostname");
strncpy(this->host, host, 255);
}
void CyanChat::setPort(unsigned int port)
{
debug("Setting port number");
this->port = port;
}
void CyanChat::showConfig()
{
using namespace std;
cout << "Current Configuration\n"
<< "Hostname: " << this->host << "\n"
<< " Port: " << this->port << "\n";
}
/******************************************************************************
* Public Methods *
******************************************************************************/
//rude::Socket *CyanChat::socket = new rude::Socket();
void CyanChat::connect()
{
assert(!connected);
debug("Connecting to cho...");
// ClientSocket socket (host, port);
connected = true;
debug("Connected!");
}
The problem is in CyanChat.h, at the "ClientSocket socket" line. ClientSocket (the socket code I tried last, which I got from here: has a constructor that wants to be initialized with a host and port. So using a simple "ClientSocket socket" here throws an error when I compile it:
Code:
CyanChat.cpp: In constructor \u2018CyanChat::CyanChat()\u2019:
CyanChat.cpp:14: error: no matching function for call to \u2018ClientSocket::ClientSocket()\u2019
ClientSocket.h:13: note: candidates are: ClientSocket::ClientSocket(std::string, int)
ClientSocket.h:10: note: ClientSocket::ClientSocket(const ClientSocket&)
If I comment the line out, as I did in the code here, the error goes away.
The idea is that the "socket" variable be a class-level variable of a ClientSocket type, but it shouldn't be initialized until connect() is called.
I've also tried using Rude Socket, with less success. The one example on this page: has them creating it as a regular object (rude::Socket socket), but then all of the examples in the API reference use a dynamic pointer (Socket *socket = new Socket).
If I adjust my code so that the socket is declared in the header file as "rude::Socket socket;", it throws this error:
Code:
/tmp/ccmJARLK.o: In function `CyanChat::~CyanChat()':
CCBot.cpp:(.text._ZN8CyanChatD1Ev[CyanChat::~CyanChat()]+0x12): undefined reference to `rude::Socket::~Socket()'
/tmp/ccf4XIJr.o: In function `CyanChat::CyanChat()':
CyanChat.cpp:(.text+0x14): undefined reference to `rude::Socket::Socket()'
CyanChat.cpp:(.text+0x50): undefined reference to `rude::Socket::~Socket()'
If I change the declaration to use *socket like a pointer it will compile with no errors. But if I try to initialize it in connect(), i.e.
Code:
*socket = new rude::Socket();
Error:
CyanChat.cpp: In member function \u2018void CyanChat::connect()\u2019:
CyanChat.cpp:109: error: no match for \u2018operator=\u2019 in \u2018*((CyanChat*)this)->CyanChat::socket = (operator new(4u), (<statement>, ((rude::Socket*)<anonymous>)))\u2019
/usr/include/rude/socket.h:114: note: candidates are: rude::Socket& rude::Socket::operator=(const rude::Socket&)
socket = new rude::Socket();
Error:
/tmp/ccCFqV6e.o: In function `CyanChat::connect()':
CyanChat.cpp:(.text+0x370): undefined reference to `rude::Socket::Socket()'
collect2: ld returned 1 exit status
So, how can I resolve this? If I can't declare a variable of type ClientSocket, is there a way for connect() to somehow "export" its own ClientSocket variable up to the class level, so that other functions I add later like send() can access it?
Thanks in advance.
Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'