Results 1 to 3 of 3

Thread: QTcpServer & QTcpSocket questions...

  1. #1
    Join Date
    Apr 2008
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QTcpServer & QTcpSocket questions...

    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:
    Qt Code:
    1. #include <QtCore/QCoreApplication>
    2. #include "IPComm.h"
    3.  
    4. int main(int argc, char *argv[])
    5. {
    6. QCoreApplication a(argc, argv);
    7.  
    8. // select "server" or "client"
    9. if(argc > 1)
    10. {
    11. printf("instan ipcomm\n");
    12. IPComm ipcomm;
    13. ipcomm.init();
    14.  
    15. if(strcmp((const char *)argv[1], "s") == 0)
    16. {
    17. // server
    18. printf("starting server\n");
    19. ipcomm.server();
    20. }
    21. else
    22. {
    23. if(strcmp((const char *)argv[1], "c") == 0)
    24. {
    25. // client
    26. printf("starting client\n");
    27. if(argc > 2)
    28. {
    29. int port = atoi((const char *)argv[1]);
    30. ipcomm.client(port);
    31. // not sure if this is correct, seems
    32. // to be the only way for this func
    33. // to get called.
    34. ipcomm.requestNewData();
    35. }
    36. else
    37. printf("Must supply port for client\n");
    38. }
    39. }
    40. }
    41. return a.exec();
    42. }
    To copy to clipboard, switch view to plain text mode 


    ipcomm.h:
    Qt Code:
    1. #pragma once
    2.  
    3. #include <QtCore/QCoreApplication>
    4. #include <QtNetwork>
    5. #include <QTcpSocket>
    6. #include <QHostAddress>
    7.  
    8. class QTcpServer;
    9. class QTcpSocket;
    10.  
    11.  
    12. enum {
    13. TCP_NONE = 0,
    14. TCP_SERVER,
    15. TCP_CLIENT
    16. };
    17.  
    18. class IPComm : public QObject
    19. {
    20.  
    21. Q_OBJECT
    22.  
    23. public:
    24. IPComm(void);
    25. ~IPComm(void);
    26.  
    27.  
    28. QTcpServer *tcpServer;
    29. QStringList fortunes;
    30.  
    31. QTcpSocket *tcpClient;
    32. QString currentFortune;
    33. quint16 blockSize;
    34.  
    35.  
    36. int tcpType;
    37. quint16 tcpPort;
    38.  
    39. void init(void);
    40.  
    41. void server(void);
    42. void client(int port);
    43.  
    44. public slots:
    45. void requestNewData(void);
    46.  
    47. private slots:
    48. void sendData(void);
    49. void readData(void);
    50. void displayError(QAbstractSocket::SocketError socketError);
    51.  
    52. };
    To copy to clipboard, switch view to plain text mode 


    ipcomm.cpp:
    Qt Code:
    1. include "IPComm.h"
    2. #include <string>
    3.  
    4. IPComm::IPComm(void)
    5. {
    6. }
    7.  
    8. IPComm::~IPComm(void)
    9. {
    10. }
    11.  
    12. void IPComm::init(void)
    13. {
    14. tcpServer = NULL;
    15. tcpClient = NULL;
    16. tcpType = TCP_NONE;
    17.  
    18. // testing data
    19. fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
    20. << tr("You've got to think about tomorrow.")
    21. << tr("You will be surprised by a loud noise.")
    22. << tr("You will feel hungry again in another hour.")
    23. << tr("You might have mail.")
    24. << tr("You cannot kill time without injuring eternity.")
    25. << tr("Computers are not intelligent. They only think they are.");
    26. }
    27.  
    28. void IPComm::server(void)
    29. {
    30. if(tcpType == TCP_NONE)
    31. {
    32. tcpServer = new QTcpServer(this);
    33. tcpType = TCP_SERVER;
    34.  
    35. // trying out different methods for setting the address
    36. // if(!tcpServer->listen(QHostAddress::LocalHost))
    37. QHostAddress qhl("10.3.23.27");
    38. if(!tcpServer->listen(qhl))
    39. printf("Unable to start the server: %s", tcpServer->errorString());
    40. else
    41. {
    42. if(tcpServer->isListening())
    43. {
    44. QHostAddress qhost = tcpServer->serverAddress();
    45. std::string qh = qhost.toString().toStdString();
    46. printf("The server address is %s\n", (char *)qh.c_str());
    47. printf("The server port is %d\n", tcpServer->serverPort());
    48.  
    49. connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendData()));
    50. }
    51. else
    52. printf("we're NOT listening!!\n");
    53. }
    54. printf("server() - done\n");
    55. }
    56. }
    57.  
    58. void IPComm::client(int port)
    59. {
    60. if(tcpType == TCP_NONE)
    61. {
    62. tcpClient = new QTcpSocket(this);
    63. tcpType = TCP_CLIENT;
    64.  
    65. tcpPort = port;
    66.  
    67. connect(tcpClient, SIGNAL(readyRead()), this, SLOT(readData()));
    68. connect(tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
    69. this, SLOT(displayError(QAbstractSocket::SocketError)));
    70.  
    71. printf("client() - done\n");
    72. }
    73. }
    74.  
    75. void IPComm::readData()
    76. {
    77. printf("readData() - begin\n");
    78.  
    79. QDataStream in(tcpClient);
    80. //in.setVersion(QDataStream::Qt_4_0);
    81.  
    82. if (blockSize == 0)
    83. {
    84. if (tcpClient->bytesAvailable() < (int)sizeof(quint16))
    85. return;
    86.  
    87. in >> blockSize;
    88. }
    89.  
    90. if (tcpClient->bytesAvailable() < blockSize)
    91. return;
    92.  
    93. QString nextFortune;
    94. in >> nextFortune;
    95.  
    96. if (nextFortune == currentFortune)
    97. {
    98. printf("readData() - requestNewData\n");
    99. QTimer::singleShot(0, this, SLOT(requestNewData()));
    100. return;
    101. }
    102.  
    103. currentFortune = nextFortune;
    104. std::string tmp = currentFortune.toStdString();
    105. printf("readData(): %s\n", (char *)(tmp.c_str()));
    106. }
    107.  
    108. void IPComm::requestNewData()
    109. {
    110. printf("requestNewData() - begin\n");
    111.  
    112. blockSize = 0;
    113. tcpClient->abort();
    114.  
    115. QString servIP = "10.3.23.27";
    116. int servPO = tcpPort;
    117.  
    118. tcpClient->connectToHost(servIP, servPO);
    119.  
    120. printf("requestNewData() - done\n");
    121. }
    122.  
    123.  
    124. void IPComm::sendData()
    125. {
    126. printf("sendData() - begin\n");
    127.  
    128. QByteArray block;
    129. QDataStream out(&block, QIODevice::WriteOnly);
    130. out.setVersion(QDataStream::Qt_4_0);
    131. out << (quint16)0;
    132. out << fortunes.at(qrand() % fortunes.size());
    133. out.device()->seek(0);
    134. out << (quint16)(block.size() - sizeof(quint16));
    135.  
    136. QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
    137. connect(clientConnection, SIGNAL(disconnected()),
    138. clientConnection, SLOT(deleteLater()));
    139.  
    140. clientConnection->write(block);
    141. clientConnection->disconnectFromHost();
    142.  
    143. printf("sendData() - done\n");
    144. }
    145.  
    146.  
    147. void IPComm::displayError(QAbstractSocket::SocketError socketError)
    148. {
    149. switch (socketError)
    150. {
    151. case QAbstractSocket::RemoteHostClosedError:
    152. printf("The connection was closed by the host.\n");
    153. break;
    154.  
    155. case QAbstractSocket::HostNotFoundError:
    156. printf("The host was not found. Please check the host name and port settings.\n");
    157. break;
    158.  
    159. case QAbstractSocket::ConnectionRefusedError:
    160. printf("The connection was refused by the peer.\n");
    161. break;
    162.  
    163. default:
    164. std::string err = tcpServer->errorString().toStdString();
    165. printf("the following error occurred: %s\n", (char *)err.c_str());
    166. break;
    167. }
    168. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2006
    Location
    England
    Posts
    18
    Thanks
    2
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QTcpServer & QTcpSocket questions...

    Hi

    You don't say what problems you're having. If it's a read/write problem, I think your problem may lie in the following areas:

    In sendData() you initialise a QByteArray with the data you intend to send, then use write(block) to send it 'over the wire'.

    In readData() you initialise QDataStream with the client socket, but in my experience you need to cast your variables to references to allow them to be written to i.e.:
    Qt Code:
    1. QDataStream in(tcpClient);
    2. in >> (quint16&) blockSize;
    To copy to clipboard, switch view to plain text mode 

    Same for the read of fortune - should be
    Qt Code:
    1. in >> (QString&) nextFortune;
    To copy to clipboard, switch view to plain text mode 

    Mixing the QByteArray/write and QDataStream >> methods together doesn't seem like a good idea in my view - stick to one or t'other!

    They are the things that jumped out at me after looking at your code.

    Mc
    It's always a long day, you can't fit 86400 into a short!

  3. #3
    Join Date
    Apr 2008
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QTcpServer & QTcpSocket questions...

    Oops! All that I and didn't specifiy the problem (I must be getting "old"). Anyways, I can't get the app to connect. I run the exe twice, once as a "server" and again as the "client".

    As an experiment I split the ipcomm class into two, ipserver and ipclient and then built 2 separate exe's. That works. The connection is made and the data is sent. However my preference is to create a single class to handle both the client and server functionality.

    thanks!

Similar Threads

  1. File Transfer with QTcpServer and QTcpSocket
    By NoRulez in forum Qt Programming
    Replies: 2
    Last Post: 21st October 2009, 18:12
  2. Replies: 3
    Last Post: 29th June 2007, 09:32
  3. Strange QTcpSocket behavior (debugged with Ethereal)
    By mdecandia in forum Qt Programming
    Replies: 23
    Last Post: 28th May 2007, 21:44
  4. Replies: 6
    Last Post: 8th January 2007, 11:24

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.