网络发送问题

时间:2010-12-20 14:43:37

标签: c++ qt4

我尝试通过网络发送数据,但我编写的服务器却没有获取数据。 这段代码适用于:

void MainWindow::send()
{
 QByteArray qbarr;
 QDataStream qdstrm(&qbarr, QIODevice::WriteOnly);
 int iCount = qlist->count();
 QProgressDialog qprogrsdSend(QString("Sending..."), QString("Cancel"), 0, iCount, this);

 qdstrm.setVersion(QDataStream::Qt_4_6);

 qprogrsdSend.setWindowModality(Qt::WindowModal);

 for(int i = 0; i < iCount; i++)
 {
  if(qprogrsdSend.wasCanceled())
   break;

  qdstrm << (quint16)0;
  qdstrm << (*qlist)[i].data();
  qdstrm.device()->seek(0);
  qdstrm << (quint16)(qbarr.size() - sizeof(quint16));

  qprogrsdSend.setValue(i);

  qtcpsoClient->write(qbarr);
  qtcpsoClient->flush();
  qtcpsoClient->waitForBytesWritten();

  qbarr.clear();
 }

 qlblStatus2->setText("File is send.");
}

但是需要很多时间从qlist发送每个elemt。现在我尝试修改方法,以便qlist中的所有元素首先保存在qbarr中。而且我发送文件。这是不起作用的代码:

void MainWindow::send()
{
 QByteArray qbarr;
 QDataStream qdstrm(&qbarr, QIODevice::WriteOnly);
 int iCount = qlist->count();
 QProgressDialog qprogrsdSend(QString("Sending..."), QString("Cancel"), 0, iCount, this);

 qdstrm.setVersion(QDataStream::Qt_4_6);

 qprogrsdSend.setWindowModality(Qt::WindowModal);

 qdstrm << (quint16)0;

 for(int i = 0; i < iCount; i++)
 {
  if(qprogrsdSend.wasCanceled())
   break;

  qdstrm << (*qlist)[i].data();

  qprogrsdSend.setValue(i);
 }

 qdstrm.device()->seek(0);
 qdstrm << (quint16)(qbarr.size() - sizeof(quint16));

 qtcpsoClient->write(qbarr);
 qtcpsoClient->flush();
 qtcpsoClient->waitForBytesWritten();

 qbarr.clear();

 qlblStatus2->setText("File is send.");
}

这是我用来读取数据的方法:

void QServerThread::onReadyRead(void)
{
 if(read == false)
 {
  read = true;
  emit reading(true);
 }

 while(!qtcpsoClient->atEnd())
 {
  QDataStream qdstrmIn(qtcpsoClient);
  QDataStream qdstrmOut(qfile);
  QByteArray qbarrData;
  quint16 qui16BlockSize = 0;
  int iVersion = qdstrmIn.version();

  qdstrmIn.setVersion(iVersion);
  qdstrmOut.setVersion(iVersion);

  if(qtcpsoClient->bytesAvailable() < (int)sizeof(quint16))
   break;

  qdstrmIn >> qui16BlockSize;

  if(qtcpsoClient->bytesAvailable() < qui16BlockSize)
   break;

  qdstrmIn >> qbarrData;

  qdstrmOut << qbarrData.data();

  qfile->flush();
 }

 read = false;
 emit reading(false);
}

我希望有人可以帮助我。 感谢

1 个答案:

答案 0 :(得分:0)

问题不在您的服务器中吗?我想你将onReadyRead连接到socket的readyRead信号。每接收一个数据块就会发出一次该信号。因此,如果您一次发送所有数据,信号可能只发出一次。我想qtcpsoClient是套接字。现在,我可以看到这种情况发生了:

在您收到大量数据之前,您问bytesAvailable() < somesize。在这种情况下,你读了一个大小,但在那之后就爆发了,在下一次阅读时你已经丢失了你的尺寸信息并阅读了垃圾。

在您发送多条短消息之前,这可能不是问题,并且在您要求数据大小之前,每条消息都设置为完全到达。虽然虫子还在那里。

旁注。在原始客户端代码中 - 为什么flush()waitForBytesWritten()在每个write之后?这可能是它如此缓慢的原因。

[编辑:根据Sergey Tachenov的评论纠正]