Results 1 to 20 of 21

Thread: TCPSocket/Server

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Wink TCPSocket/Server

    I am making a simple file transfer app based on Threaded Fortune Server. I am running into an issue where I am losing the last couple of bytes from my file.

    Client Code:
    Qt Code:
    1. file.open(QIODevice::ReadOnly);
    2. DataStream infile(&file);
    3. DataStream in(socket);
    4. int count = 0;
    5. char point[1500];
    6. while(!infile.atEnd())
    7. {
    8. count = infile.readRawData(point,1500);
    9. in.writeRawData(point,count);
    10. TCPSocket->waitForBytesWritten(300);
    11. }
    To copy to clipboard, switch view to plain text mode 

    Server Side:
    This function is connected to readyRead
    Qt Code:
    1. void ReadNow{
    2. QDataStream input(socket);
    3. QDataStream output(file);
    4. char point[1500];
    5. int count = 0;
    6. while(!input.atEnd())
    7. {
    8. count = input.readRawData(point,1500);
    9. totalbytes+=count;
    10. output.writeRawData(point,count);
    11. }
    12. file.waitForBytesWritten(1000);
    13. }
    To copy to clipboard, switch view to plain text mode 

    I am unsure of where the missing bytes are going.

  2. #2
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCPSocket/Server

    Oh, I see you posted some code .
    The code seems ok.
    Try comparing the file size(as reported by a file browser) with the size you read in the client and with totalbytes from the server.
    Which is the wrong one?

    Also, in the client, test the return values of writeRawData and waitForBytesWritten. Do they ever return -1?

    Regards

  3. The following user says thank you to marcel for this useful post:

    TheGrimace (10th August 2007)

  4. #3
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    I just checked and it is wrong on the server side. Also worth noting: it never seems to get the full 1500 only about 1150. This may just be due to packetization, though. I am testing the -1 issue now.

    Thank you for your quick responses Marcel. The reason i can post code this time is this is just a test app and not a company product.

  5. #4
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    Darn! It is not returning -1. I am not sure where the missing bytes are.

  6. #5
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCPSocket/Server

    Well, you either don't catch all the data on the server, or you don't send it all.

    Do you use the QTcpSocket::readyRead signal? You should connect the ReadNow function to it and read all the data at once, not only 1500 bytes...

    Anyway, sending ~1.5k of data and sleeping 300ms at most is not exactly optimal.
    You could send larger quantities and QTcpSocket is buffered.

    BTW: waitForBytesWritten returns false on timeout or error, not -1.

    Regards

  7. The following user says thank you to marcel for this useful post:

    TheGrimace (10th August 2007)

  8. #6
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    I know I can send more, I just want to get it working before I accelerated it. I will check waitforbyteswritten now. Thank You.

  9. #7
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    Just checked. It doesn't seem to return false either.

    The ReadNow function is connected to readyRead. It is called about 400 (exageration) times.

  10. #8
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCPSocket/Server

    Just for curiosity: remove(in the server) file.waitForBytesWritten.
    There is no need for it, since it is buffered. At most you can call flush on it, but that is not needed either.

    Regards

  11. The following user says thank you to marcel for this useful post:

    TheGrimace (10th August 2007)

  12. #9
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    Is there any reason that the readyread signal would not be raised at the very end of the data?

    (Sorry about the triple post. I wish there were a way to edit forum posts on this site)

  13. #10
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    No change after removing the waitForBytesWritten. The data is always lost at the end of the file and it is never the same amount. It varies between 1-10 K.

  14. #11
    Join Date
    Feb 2006
    Location
    Romania
    Posts
    2,744
    Thanks
    8
    Thanked 541 Times in 521 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: TCPSocket/Server

    No, it should be emitted every time. And I am sure it is.

    Regards

  15. The following user says thank you to marcel for this useful post:

    TheGrimace (10th August 2007)

  16. #12
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    I just tried comparing the bytes written to disk to the bytes received from the socket. They are the same. So that isn't it.

  17. #13
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    Full Code: (just in case it is somewhere else) (btw I know this code is messy and much of it is not used. I was just making this app quick and for testing only)

    Client:
    Qt Code:
    1. MyClient::MyClient()
    2. {
    3. actions = 0;
    4. startUDP = new QPushButton("StartUDP");
    5. startTCP = new QPushButton("StartTCP");
    6. Browse1 = new QPushButton("Browse");
    7. Browse2 = new QPushButton("Browse");
    8. portNumberUDP = new QLineEdit("");
    9. portNumberTCP = new QLineEdit("9654");
    10. TCPfile = new QLineEdit("");
    11. UDPfile = new QLineEdit("");
    12. nic = new QLineEdit("10.24.74.115");
    13. theLayout = new QGridLayout;
    14. lblStatusUDP = new QLabel;
    15. lblStatusTCP = new QLabel;
    16. theLayout->addWidget(portNumberUDP,0,2);
    17. theLayout->addWidget(portNumberTCP,1,2);
    18. theLayout->addWidget(Browse1, 0, 1);
    19. theLayout->addWidget(Browse2, 1, 1);
    20. theLayout->addWidget(startUDP,0,3);
    21. theLayout->addWidget(nic,0,4);
    22. theLayout->addWidget(TCPfile,1,0);
    23. theLayout->addWidget(UDPfile,0,0);
    24. theLayout->addWidget(startTCP,1,3);
    25. theLayout->addWidget(lblStatusUDP,2,0,1,3);
    26. theLayout->addWidget(lblStatusTCP,3,0,1,3);
    27. setLayout(theLayout);
    28.  
    29. TCPSocket = new QTcpSocket();
    30.  
    31. connect(startUDP, SIGNAL(clicked()), this, SLOT(requestAnotherUDP()));
    32. connect(startTCP, SIGNAL(clicked()), this, SLOT(requestAnotherTCP()));
    33. connect(Browse1,SIGNAL(clicked()),this,SLOT(catchBrowse1()));
    34. connect(Browse2,SIGNAL(clicked()),this,SLOT(catchBrowse2()));
    35. connect(TCPSocket, SIGNAL(connected()) , this , SLOT(catchConnected()));
    36. }
    37. void MyClient::requestAnotherUDP()
    38. {
    39. actions++;
    40. QUdpSocket* UDPSocket = new QUdpSocket;
    41. QFile file(UDPfile->text());
    42. file.open(QIODevice::ReadOnly);
    43. QTextStream infile(&file);
    44.  
    45. int sendData = qrand() % 10;
    46. startUDP->setEnabled(false);
    47. blockSize = 0;
    48. QByteArray block, BigBlock;
    49. UDPSocket->abort();
    50. UDPSocket->connectToHost(nic->text(),portNumberUDP->text().toInt());
    51. lblStatusUDP->setText("UDP: " + QString::number(actions) + ". Sending file to "+nic->text()+" on port " + portNumberUDP->text());
    52. QDataStream in(UDPSocket);
    53. in.setVersion(QDataStream::Qt_4_0);
    54. while(!infile.atEnd())
    55. {
    56. infile >> block;
    57. block.append(' ');
    58. BigBlock.append(block);
    59. }
    60. in.writeBytes(BigBlock,BigBlock.length());
    61. UDPSocket->disconnect();
    62. UDPSocket->waitForDisconnected(3000);
    63. lblStatusUDP->setText("UDP: " + QString::number(actions) + ". Sent file to "+nic->text()+" on port " + portNumberUDP->text());
    64. startUDP->setEnabled(true);
    65. }
    66. void MyClient::requestAnotherTCP()
    67. {
    68. actions++;
    69. startTCP->setEnabled(false);
    70. blockSize = 0;
    71. TCPSocket->abort();
    72. TCPSocket->connectToHost(nic->text(),portNumberTCP->text().toInt());
    73. TCPSocket->setReadBufferSize(50000000);
    74. }
    75.  
    76. void MyClient::catchConnected()
    77. {
    78. qDebug("Connected");
    79.  
    80. QByteArray block, BigBlock;
    81. QFile file(TCPfile->text());
    82. file.open(QIODevice::ReadOnly);
    83. QDataStream infile(&file);
    84. char point[1500];
    85.  
    86. if(TCPSocket->isValid())
    87. {
    88. lblStatusTCP->setText("TCP: " + QString::number(actions) + ". Sending file to "+nic->text()+" on port " + portNumberTCP->text());
    89. QDataStream in(TCPSocket);
    90. in.setVersion(QDataStream::Qt_4_3);
    91. QFile newfile("Test.dat");
    92. newfile.open(QIODevice::WriteOnly);
    93. QDataStream fi(&newfile);
    94. int totalbytes = 0;
    95. int totalbytes2 = 0;
    96. int count = -1;
    97. int count2 = -1;
    98. while(!infile.atEnd())
    99. {
    100. count = infile.readRawData(point,1500);
    101. count2 = in.writeRawData(point,count);
    102. if(!TCPSocket->waitForBytesWritten(300))
    103. {
    104. QMessageBox::about(this,"False","False");
    105. }
    106. totalbytes2 += fi.writeRawData(point,count);
    107. if(count2 == -1)
    108. {
    109. QMessageBox::about(this,"-1","-1");
    110. }
    111. }
    112. TCPSocket->waitForBytesWritten(3000);
    113. newfile.waitForBytesWritten(3000);
    114. newfile.close();
    115.  
    116. startTCP->setEnabled(true);
    117. TCPSocket->flush();
    118. TCPSocket->disconnectFromHost();
    119. TCPSocket->waitForDisconnected(-1);
    120. lblStatusTCP->setText("TCP: " + QString::number(actions) + ". Sent file to "+nic->text()+" on port " + portNumberTCP->text());
    121. }
    122.  
    123.  
    124. }
    125. void MyClient::catchBrowse1()
    126. {
    127. QString strfile = QFileDialog::getOpenFileName(this,"UDP File");
    128.  
    129. if(!strfile.isEmpty())
    130. {
    131. UDPfile->setText(strfile);
    132. }
    133. }
    134. void MyClient::catchBrowse2()
    135. {
    136. QString strfile = QFileDialog::getOpenFileName(this,"TCP File");
    137.  
    138. if(!strfile.isEmpty())
    139. {
    140. TCPfile->setText(strfile);
    141. }
    142. }
    To copy to clipboard, switch view to plain text mode 

    Server:
    Qt Code:
    1. #include "testserver.h"
    2.  
    3. tcpServer::tcpServer(): QWidget()
    4. {
    5. node = 1;
    6. TCPServ = new QTcpServer;
    7. connect(TCPServ,SIGNAL(newConnection()),this,SLOT(createNewSocket()));
    8. txtEdit = new QTextEdit;
    9. QGridLayout* theLayout = new QGridLayout;
    10. port = new QLineEdit;
    11. nic = new QComboBox;
    12. start = new QPushButton;
    13. start->setText("Start");
    14. start->setCheckable(true);
    15. connect(start,SIGNAL(clicked()),this,SLOT(catchstart()));
    16. theLayout->addWidget(port,0,0);
    17. theLayout->addWidget(nic,0,1);
    18. theLayout->addWidget(start,0,2);
    19. theLayout->addWidget(txtEdit,1,0,1,3);
    20. port->setText("port");
    21.  
    22. QList<QHostAddress> nicList = QNetworkInterface::allAddresses();
    23. for(int i = nicList.size()-1; i>=0; i--)
    24. {
    25. this->nic->insertItem(i, nicList[i].toString());
    26. }
    27. setLayout(theLayout);
    28. }
    29. void tcpServer::createNewSocket()
    30. {
    31. QTcpSocket * thesocket = TCPServ->nextPendingConnection();
    32. ServerNode* newNode = new ServerNode(this,thesocket,this->txtEdit, node++);
    33.  
    34. }
    35. void tcpServer::catchstart()
    36. {
    37. if(start->isChecked())
    38. {
    39. start->setText("Stop");
    40. TCPServ->listen(QHostAddress(nic->currentText()),port->text().toInt());
    41. }
    42. else
    43. {
    44. start->setText("Start");
    45. TCPServ->close();
    46. }
    47. }
    48. void tcpServer::changeText(QString newstring)
    49. {
    50. txtEdit->append("\n"+newstring);
    51. }
    52. ServerNode::ServerNode()
    53. {
    54. }
    55. ServerNode::ServerNode(tcpServer* parent,QTcpSocket* thesocket,QTextEdit* point, int intnode)
    56. {
    57. node = intnode;
    58. totalbytes = 0;
    59. connect(thesocket,SIGNAL(readyRead()),this,SLOT(readNow()));
    60. //connect(thesocket,SIGNAL(disconnected()),this,SLOT(fileDone()));
    61. input.setDevice(thesocket);
    62. socket = thesocket;
    63. file .setFileName(QString("Test_%1").arg(node));
    64. file.open(QIODevice::Append);
    65. output.setDevice(&file);
    66. }
    67. void ServerNode::readNow()
    68. {
    69. int count = 0;
    70. int count2 = 0;
    71. char point[1500];
    72.  
    73. QByteArray oneBlock;
    74.  
    75. while(!input.atEnd())
    76. {
    77. count = input.readRawData(point,1500);
    78. if(count == -1)
    79. {
    80. QMessageBox::about(0,"-1","-1");
    81. }
    82. totalbytes+=count;
    83. count2 = output.writeRawData(point,count);
    84. if(count != count2)
    85. {
    86. QMessageBox::about(0,"1!=2","1!=2");
    87. }
    88. }
    89. //file.waitForBytesWritten(1000);
    90. }
    91. void ServerNode::run()
    92. {
    93. }
    94. void ServerNode::fileDone()
    95. {
    96. QFile::rename(QString("Temp__%1.dat").arg(node),QString("Complete__%1.dat").arg(node));
    97. }
    To copy to clipboard, switch view to plain text mode 

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
  •  
Qt is a trademark of The Qt Company.