0

I try to write simple server, using Qt and C++. Here is code:

   #include "mytcpserver.h"

MyTcpServer::MyTcpServer(QObject *parent) :
    QObject(parent)
{
    server = new QTcpServer(this);


    // whenever a user connects, it will emit signal
    connect(server, SIGNAL(newConnection()),
            this, SLOT(newConnection()));



    if(!server->listen(QHostAddress("127.0.0.1"), 3333))
    {
        qDebug() << "Server could not start";
    }
    else
    {
        qDebug() << "Server started!";
    }
}

   void MyTcpServer::on_readyRead()
  {
QTcpSocket * senderSocket = dynamic_cast<QTcpSocket *>(sender());
if (senderSocket)
{
    qDebug() << "reading data";
    qDebug() << senderSocket->readAll();
}
  }

  void MyTcpServer::newConnection()
{
    // need to grab the socket
QTcpSocket *sok=new QTcpSocket();
sok = server->nextPendingConnection();
if (sok)
{
    connect(sok,SIGNAL(readyRead()),this,SLOT(on_readyRead()));
    connect(sok,SIGNAL(disconnected()),sok,SLOT(deleteLater()));
}
sok->write("Writing");
}

And part of client on PHP:

$address = "127.0.0.1";
$service_port = "3333";
echo "Attempting to connect to '$address' on port '$service_port'...";
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
    echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socke$
} else {
    echo "OK.\n";
}

$in = "HEAD / HTTP";
$out = '';

echo "Sending HTTP HEAD request...";
socket_write($socket, $in, strlen($in));
echo "OK.\n";
echo "Reading response:\n\n";
while ($out = socket_read($socket, 2048)) {
    echo $out;
}

The problem is that I can't read from php client, specifically, signal readyRead isn't emitted. Also if i try to type in command line: telnet 127.0.0.1 3333 then server only responds "Writing" and exit.

galinette
  • 8,896
  • 2
  • 36
  • 87
Robert
  • 371
  • 1
  • 5
  • 15
  • You removed sok from the class, not the local variable in newConnection(). And now the readyRead signal is not connected to anything. Connect as soon as you get the socket from nextPendingConnection() – galinette May 11 '14 at 17:13
  • You close the incoming connection as soon as you get it from nextPendingConnection! How do you expect it to receive data? Don't close it! – galinette May 11 '14 at 17:14
  • What is sok referring to in on_readyRead() ?? – galinette May 11 '14 at 17:15

1 Answers1

1

Try this:

#include "mytcpserver.h"

MyTcpServer::MyTcpServer(QObject *parent) :
    QObject(parent)
{
    server = new QTcpServer(this);

    // whenever a user connects, it will emit signal
    connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));


    if(!server->listen(QHostAddress("127.0.0.1"), 3333))
    {
        qDebug() << "Server could not start";
    }
    else
    {
        qDebug() << "Server started!";
    }
}

void MyTcpServer::on_readyRead()
{ 
    QTcpSocket * senderSocket = dynamic_cast<QTcpSocket*>(sender());
    if(senderSocket)
    {
        qDebug() << "reading data";
        qDebug() << senderSocket->readAll();
    }
}

void MyTcpServer::newConnection()
{
    // need to grab the socket
    QTcpSocket * newSocket = server->nextPendingConnection();
    if(newSocket)
    {
        connect(newSocket ,SIGNAL(readyRead()),this,SLOT(on_readyRead()));

        //Additionnal auto clean-up without keeping track of the pointer
        connect(newSocket ,SIGNAL(disconnected()),newSocket ,SLOT(deleteLater()));
    }
}

(When you declare this:

QTcpSocket *sok=new QTcpSocket();

This creates a local QTcpSocket pointer, which hides the sok member of your class. Also, you create a QTcpSocket with new, and lose it at the next line (memory leak)

sok = server->nextPendingConnection();

So the sok member variable of your class is never used with an incoming connection.

You are using a member variable called sok in MyTcpServer class and a local variable sok in MyTcpServer::on_readyRead, this is a bad idea.

Proper use of QTcpServer would be:

  • Store incoming connections in a member variable pointer
  • Connect its readyRead signal
galinette
  • 8,896
  • 2
  • 36
  • 87
  • And this way, it also allows multiple concurrent connections, without even storing an array of QTcpSocket pointers – galinette May 11 '14 at 17:29