Page 1 of 2 12 LastLast
Results 1 to 20 of 21

Thread: TCPSocket/Server

  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 

  18. #14
    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

    In readNow, try reading all the available data at once, without the data stream wrapped around the socket.
    Use the QIODevice API directly.
    If it works, then it means there is a problem in the data stream handling.

    Regards

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

    TheGrimace (10th August 2007)

  20. #15
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: TCPSocket/Server

    I tried changing the readrawdata command in both the server and the client socket writes/reads to write and read commands directly on the socket. This does not seem to have made a difference.

  21. #16
    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

    OK. Weird enough.
    I'm gonna write a small sample( still based on the fortune server/client) to see what's wrong.

    I'll post back when its done.

    regards

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

    Default Re: TCPSocket/Server

    Thank you!

    Just so you know I only have the problem with files over a meg or so in size.

  23. #18
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Smile Re: TCPSocket/Server

    I will not be able to check this forum until monday. Thank you for all the help you have given me so far. It is refreshing to know that the mistake was not an obvious one.

    Again, Thank You,

    The Grimace

  24. #19
    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, I couldn't find anything.
    I modified the samples and attached them. Here the server sends the file. I used an 8.42mb file and a 15.6mb one, and I couldn't reproduce the problem.

    You can test on your side.
    The send/receive methods are similar to yours. I also used QDataStream's.

    Everything happens in Client::readFortune(receive file) and in FortuneThread::run( sends the file).

    The file name is hardcoded, so you might want to modify that.

    Regards
    Attached Files Attached Files

  25. The following 3 users say thank you to marcel for this useful post:

    BeakerBob (29th September 2008), njuFerret (12th March 2011), TheGrimace (13th August 2007)

  26. #20
    Join Date
    May 2007
    Posts
    90
    Thanks
    40
    Qt products
    Qt4
    Platforms
    Windows

    Talking Re: TCPSocket/Server

    Your code worked for me as well. I am still not sure what the issue was, but I was able to integrate your code into mine to get the app working.

    Thank you very much for all your help.

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.