Greetings,
First, great site... very helpful. Second, I'm a QT newbie but have been programming for 25 years.
I'm having some difficulty getting a simple QTcpServer & QTcpSocket working. It's just a console app that acts as either a server or a client. It's base on the Fortune demo, without the GUI code. I've ran the fortune demo on the same PC where I'm writing the app and it works just fine so I know the problem is related to something I've done incorrectly.
I've already searched this forum for answers but I haven't found anything that seems to apply to this problem. So any help is appreciated! Thanks in advance!
Here's all of the code (main.cpp, ipcomm.h, ipcomm.cpp - built w/ MSVS 2005) -
main.cpp:
#include <QtCore/QCoreApplication>
#include "IPComm.h"
int main(int argc, char *argv[])
{
// select "server" or "client"
if(argc > 1)
{
printf("instan ipcomm\n");
IPComm ipcomm;
ipcomm.init();
if(strcmp((const char *)argv[1], "s") == 0)
{
// server
printf("starting server\n");
ipcomm.server();
}
else
{
if(strcmp((const char *)argv[1], "c") == 0)
{
// client
printf("starting client\n");
if(argc > 2)
{
int port = atoi((const char *)argv[1]);
ipcomm.client(port);
// not sure if this is correct, seems
// to be the only way for this func
// to get called.
ipcomm.requestNewData();
}
else
printf("Must supply port for client\n");
}
}
}
return a.exec();
}
#include <QtCore/QCoreApplication>
#include "IPComm.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// select "server" or "client"
if(argc > 1)
{
printf("instan ipcomm\n");
IPComm ipcomm;
ipcomm.init();
if(strcmp((const char *)argv[1], "s") == 0)
{
// server
printf("starting server\n");
ipcomm.server();
}
else
{
if(strcmp((const char *)argv[1], "c") == 0)
{
// client
printf("starting client\n");
if(argc > 2)
{
int port = atoi((const char *)argv[1]);
ipcomm.client(port);
// not sure if this is correct, seems
// to be the only way for this func
// to get called.
ipcomm.requestNewData();
}
else
printf("Must supply port for client\n");
}
}
}
return a.exec();
}
To copy to clipboard, switch view to plain text mode
ipcomm.h:
#pragma once
#include <QtCore/QCoreApplication>
#include <QtNetwork>
#include <QTcpSocket>
#include <QHostAddress>
enum {
TCP_NONE = 0,
TCP_SERVER,
TCP_CLIENT
};
{
Q_OBJECT
public:
IPComm(void);
~IPComm(void);
quint16 blockSize;
int tcpType;
quint16 tcpPort;
void init(void);
void server(void);
void client(int port);
public slots:
void requestNewData(void);
private slots:
void sendData(void);
void readData(void);
};
#pragma once
#include <QtCore/QCoreApplication>
#include <QtNetwork>
#include <QTcpSocket>
#include <QHostAddress>
class QTcpServer;
class QTcpSocket;
class QHostAddress;
enum {
TCP_NONE = 0,
TCP_SERVER,
TCP_CLIENT
};
class IPComm : public QObject
{
Q_OBJECT
public:
IPComm(void);
~IPComm(void);
QTcpServer *tcpServer;
QStringList fortunes;
QTcpSocket *tcpClient;
QString currentFortune;
quint16 blockSize;
int tcpType;
quint16 tcpPort;
void init(void);
void server(void);
void client(int port);
public slots:
void requestNewData(void);
private slots:
void sendData(void);
void readData(void);
void displayError(QAbstractSocket::SocketError socketError);
};
To copy to clipboard, switch view to plain text mode
ipcomm.cpp:
include "IPComm.h"
#include <string>
IPComm::IPComm(void)
{
}
IPComm::~IPComm(void)
{
}
void IPComm::init(void)
{
tcpServer = NULL;
tcpClient = NULL;
tcpType = TCP_NONE;
// testing data
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
<< tr("You've got to think about tomorrow.")
<< tr("You will be surprised by a loud noise.")
<< tr("You will feel hungry again in another hour.")
<< tr("You might have mail.")
<< tr("You cannot kill time without injuring eternity.")
<< tr("Computers are not intelligent. They only think they are.");
}
void IPComm::server(void)
{
if(tcpType == TCP_NONE)
{
tcpType = TCP_SERVER;
// trying out different methods for setting the address
// if(!tcpServer->listen(QHostAddress::LocalHost))
if(!tcpServer->listen(qhl))
printf("Unable to start the server: %s", tcpServer->errorString());
else
{
if(tcpServer->isListening())
{
std::string qh = qhost.toString().toStdString();
printf("The server address is %s\n", (char *)qh.c_str());
printf("The server port is %d\n", tcpServer->serverPort());
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendData()));
}
else
printf("we're NOT listening!!\n");
}
printf("server() - done\n");
}
}
void IPComm::client(int port)
{
if(tcpType == TCP_NONE)
{
tcpType = TCP_CLIENT;
tcpPort = port;
connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readData()));
printf("client() - done\n");
}
}
void IPComm::readData()
{
printf("readData() - begin\n");
//in.setVersion(QDataStream::Qt_4_0);
if (blockSize == 0)
{
if (tcpClient->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if (tcpClient->bytesAvailable() < blockSize)
return;
in >> nextFortune;
if (nextFortune == currentFortune)
{
printf("readData() - requestNewData\n");
QTimer::singleShot(0,
this,
SLOT(requestNewData
()));
return;
}
currentFortune = nextFortune;
std::string tmp = currentFortune.toStdString();
printf("readData(): %s\n", (char *)(tmp.c_str()));
}
void IPComm::requestNewData()
{
printf("requestNewData() - begin\n");
blockSize = 0;
tcpClient->abort();
int servPO = tcpPort;
tcpClient->connectToHost(servIP, servPO);
printf("requestNewData() - done\n");
}
void IPComm::sendData()
{
printf("sendData() - begin\n");
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
QTcpSocket *clientConnection
= tcpServer
->nextPendingConnection
();
connect(clientConnection, SIGNAL(disconnected()),
clientConnection, SLOT(deleteLater()));
clientConnection->write(block);
clientConnection->disconnectFromHost();
printf("sendData() - done\n");
}
{
switch (socketError)
{
printf("The connection was closed by the host.\n");
break;
printf("The host was not found. Please check the host name and port settings.\n");
break;
printf("The connection was refused by the peer.\n");
break;
default:
std::string err = tcpServer->errorString().toStdString();
printf("the following error occurred: %s\n", (char *)err.c_str());
break;
}
}
include "IPComm.h"
#include <string>
IPComm::IPComm(void)
{
}
IPComm::~IPComm(void)
{
}
void IPComm::init(void)
{
tcpServer = NULL;
tcpClient = NULL;
tcpType = TCP_NONE;
// testing data
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
<< tr("You've got to think about tomorrow.")
<< tr("You will be surprised by a loud noise.")
<< tr("You will feel hungry again in another hour.")
<< tr("You might have mail.")
<< tr("You cannot kill time without injuring eternity.")
<< tr("Computers are not intelligent. They only think they are.");
}
void IPComm::server(void)
{
if(tcpType == TCP_NONE)
{
tcpServer = new QTcpServer(this);
tcpType = TCP_SERVER;
// trying out different methods for setting the address
// if(!tcpServer->listen(QHostAddress::LocalHost))
QHostAddress qhl("10.3.23.27");
if(!tcpServer->listen(qhl))
printf("Unable to start the server: %s", tcpServer->errorString());
else
{
if(tcpServer->isListening())
{
QHostAddress qhost = tcpServer->serverAddress();
std::string qh = qhost.toString().toStdString();
printf("The server address is %s\n", (char *)qh.c_str());
printf("The server port is %d\n", tcpServer->serverPort());
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendData()));
}
else
printf("we're NOT listening!!\n");
}
printf("server() - done\n");
}
}
void IPComm::client(int port)
{
if(tcpType == TCP_NONE)
{
tcpClient = new QTcpSocket(this);
tcpType = TCP_CLIENT;
tcpPort = port;
connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readData()));
connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(displayError(QAbstractSocket::SocketError)));
printf("client() - done\n");
}
}
void IPComm::readData()
{
printf("readData() - begin\n");
QDataStream in(tcpClient);
//in.setVersion(QDataStream::Qt_4_0);
if (blockSize == 0)
{
if (tcpClient->bytesAvailable() < (int)sizeof(quint16))
return;
in >> blockSize;
}
if (tcpClient->bytesAvailable() < blockSize)
return;
QString nextFortune;
in >> nextFortune;
if (nextFortune == currentFortune)
{
printf("readData() - requestNewData\n");
QTimer::singleShot(0, this, SLOT(requestNewData()));
return;
}
currentFortune = nextFortune;
std::string tmp = currentFortune.toStdString();
printf("readData(): %s\n", (char *)(tmp.c_str()));
}
void IPComm::requestNewData()
{
printf("requestNewData() - begin\n");
blockSize = 0;
tcpClient->abort();
QString servIP = "10.3.23.27";
int servPO = tcpPort;
tcpClient->connectToHost(servIP, servPO);
printf("requestNewData() - done\n");
}
void IPComm::sendData()
{
printf("sendData() - begin\n");
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()),
clientConnection, SLOT(deleteLater()));
clientConnection->write(block);
clientConnection->disconnectFromHost();
printf("sendData() - done\n");
}
void IPComm::displayError(QAbstractSocket::SocketError socketError)
{
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
printf("The connection was closed by the host.\n");
break;
case QAbstractSocket::HostNotFoundError:
printf("The host was not found. Please check the host name and port settings.\n");
break;
case QAbstractSocket::ConnectionRefusedError:
printf("The connection was refused by the peer.\n");
break;
default:
std::string err = tcpServer->errorString().toStdString();
printf("the following error occurred: %s\n", (char *)err.c_str());
break;
}
}
To copy to clipboard, switch view to plain text mode
Bookmarks