• 7197阅读
  • 3回复

[求助]:TCP/IP的使用请帮忙看一下 [复制链接]

上一主题 下一主题
离线zhendeyue
 
只看楼主 倒序阅读 楼主  发表于: 2006-12-24
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
我在急着搞TCP/IP协议的client和server端,但是我点击client的start还没法数据时,server的进度条走满后就自动关闭了,我没有关啊,我想让他们一直保持通讯直到关闭整个窗口。另外在传文件时server端打不开文件,传数据流时问题也很严重,这样怎么敢用啊。肯请大家帮忙看一下,小女感激不尽。
server.cpp

static const int TotalBytes = 50 * 1024 * 1024;
static const int PayloadSize = 65536;
static const int port = 5600;

Dialog::Dialog(QWidget *parent)
  : QDialog(parent)
{
  serverProgressBar = new QProgressBar;
  serverStatusLabel = new QLabel(tr("Server ready"));

  infoText = new QTextEdit;
  quitButton = new QPushButton(tr("&Quit"));

  serverPort = new QLineEdit;
  serverIp = new QLineEdit;

  buttonBox = new QDialogButtonBox;
  buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

  QApplication::setOverrideCursor(Qt::WaitCursor);

  bytesWritten = 0;
  bytesReceived = 0;

  while (!tcpServer.isListening() && !tcpServer.listen(QHostAddress::Any,port)) {
      QMessageBox::StandardButton ret = QMessageBox::critical(this,tr("Loopback"),tr("Unable to start the test: %1.")
                          .arg(tcpServer.errorString()),QMessageBox::Retry|QMessageBox::Cancel);
      if (ret == QMessageBox::Cancel)
        return;
  }

  serverStatusLabel->setText(tr("Listening"));
  infoString=QString::number(tcpServer.serverPort());
  serverPort->setText(infoString);
  infoString=tcpServer.serverAddress().toString();
  serverIp->setText(infoString);
  connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
  connect(&tcpServer, SIGNAL(newConnection()),this,SLOT(acceptConnection()));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->addWidget(serverProgressBar);
  mainLayout->addWidget(serverStatusLabel);
  mainLayout->addWidget(infoText);
  mainLayout->addWidget(serverPort);
  mainLayout->addWidget(serverIp);
  mainLayout->addStretch(1);
  mainLayout->addSpacing(13);
  mainLayout->addWidget(buttonBox);
  setLayout(mainLayout);

  setWindowTitle(tr("My Server"));
}

void Dialog::acceptConnection()
{
  tcpServerConnection = tcpServer.nextPendingConnection();
  connect(tcpServerConnection, SIGNAL(readyRead()),
        this, SLOT(updateServerProgress()));
  connect(tcpServerConnection, SIGNAL(readyRead()),this,SLOT(ReceiveFile()));
  connect(tcpServerConnection, SIGNAL(error(QAbstractSocket::SocketError)),
        this, SLOT(displayError(QAbstractSocket::SocketError)));
  //connect(tcpServerConnection, SIGNAL(readyRead()),this,SLOT(socketReadyRead()));

  serverStatusLabel->setText(tr("Accepted connection"));

  //tcpServer.close();
}

void Dialog::updateServerProgress()
{
  bytesReceived += (int)tcpServerConnection->bytesAvailable();
  tcpServerConnection->readAll();

  serverProgressBar->setMaximum(TotalBytes);
  serverProgressBar->setValue(bytesReceived);
  serverStatusLabel->setText(tr("Received %1MB")
                    .arg(bytesReceived / (1024 * 1024)));

  if (bytesReceived == TotalBytes) {
      startButton->setEnabled(true);
      QApplication::restoreOverrideCursor();
  }
}

void Dialog::displayError(QAbstractSocket::SocketError socketError)
{
  if (socketError == QTcpSocket::RemoteHostClosedError)
      return;

  QMessageBox::information(this, tr("Network error"),
                    tr("The following error occurred: %1.")
                    .arg(tcpServer.errorString()));

  tcpServer.close();
  serverProgressBar->reset();
  serverStatusLabel->setText(tr("Server ready"));
  startButton->setEnabled(true);
  QApplication::restoreOverrideCursor();
}

void Dialog::ReceiveFile()
{
int filesize = 0;
int readsize = 0;
QString fileName;
QDataStream in(tcpServerConnection);

in >> filesize;
in >> fileName;
if(filesize>0){
QFile file(fileName);
if (!file.open(QFile::WriteOnly | QFile::Append))
{
  QMessageBox::warning(this,"error","can not open the file!");
  return;  
}                          
while (1)
{
  if( clientConnection->isReadable())
  {
    int receivesize = clientConnection->bytesAvailable();
    char buf[receivesize];
    clientConnection->read(buf, receivesize);
    file.write(buf, receivesize);
    readsize += receivesize;
    infoText->insertPlainText(buf);
    delete []buf;
    if(readsize == filesize) break;
  }            
}//while
  file.close();
}
else{
  while ( tcpServerConnection->canReadLine() ) {
        infoText->append( tcpServerConnection->readLine() );
    }
}              
}

client.cpp

static const int TotalBytes = 50 * 1024 * 1024;
static const int PayloadSize = 65536;
static const int port = 5600;

Dialog::Dialog(QWidget *parent)
  : QDialog(parent)
{
  clientProgressBar = new QProgressBar;
  clientStatusLabel = new QLabel(tr("Client ready"));
     
  QHBoxLayout *hb = new QHBoxLayout;
  inputText = new QLineEdit;
  QPushButton *send = new QPushButton( tr("Send"));
  QPushButton *sendfile = new QPushButton(tr("Send File"));

  hb->addWidget(inputText);
  hb->addWidget(send);

  connect( send, SIGNAL(clicked()), this,SLOT(sendToServer()) );
  connect(sendfile, SIGNAL(clicked()), this, SLOT(SendFile()));
  startButton = new QPushButton(tr("&Start"));
  quitButton = new QPushButton(tr("&Quit"));

  buttonBox = new QDialogButtonBox;
  buttonBox->addButton(startButton, QDialogButtonBox::ActionRole);
  buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole);

  connect(startButton, SIGNAL(clicked()), this, SLOT(start()));
  connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
  connect(&tcpClient, SIGNAL(connected()), this, SLOT(startTransfer()));
  connect(&tcpClient, SIGNAL(bytesWritten(qint64)),
        this, SLOT(updateClientProgress(qint64)));
  connect(&tcpClient, SIGNAL(error(QAbstractSocket::SocketError)),
        this, SLOT(displayError(QAbstractSocket::SocketError)));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  mainLayout->addWidget(clientProgressBar);
  mainLayout->addWidget(clientStatusLabel);
  mainLayout->addLayout(hb);
  mainLayout->addWidget(sendfile);
  mainLayout->addStretch(1);
  mainLayout->addSpacing(10);
  mainLayout->addWidget(buttonBox);
  setLayout(mainLayout);

  setWindowTitle(tr("My client"));
}

void Dialog::start()
{
  startButton->setEnabled(false);

  QApplication::setOverrideCursor(Qt::WaitCursor);

  bytesWritten = 0;
  bytesReceived = 0;

  clientStatusLabel->setText(tr("Connecting"));
  tcpClient.connectToHost(QHostAddress::Any, port);
 
}

void Dialog::startTransfer()
{
  bytesToWrite = TotalBytes - (int)tcpClient.write(QByteArray(PayloadSize, '@'));
  clientStatusLabel->setText(tr("Connected"));
}

void Dialog::updateClientProgress(qint64 numBytes)
{
  bytesWritten += (int)numBytes;
  if (bytesToWrite > 0)
      bytesToWrite -= (int)tcpClient.write(QByteArray(qMin(bytesToWrite, PayloadSize), '@'));

  clientProgressBar->setMaximum(TotalBytes);
  clientProgressBar->setValue(bytesWritten);
  clientStatusLabel->setText(tr("Sent %1MB")
                    .arg(bytesWritten / (1024 * 1024)));
}

void Dialog::displayError(QAbstractSocket::SocketError socketError)
{
  if (socketError == QTcpSocket::RemoteHostClosedError)
      return;

  QMessageBox::information(this, tr("Network error"),
                    tr("The following error occurred: %1.")
                    .arg(tcpClient.errorString()));

  tcpClient.close();
  clientProgressBar->reset();
  clientStatusLabel->setText(tr("Client ready"));
  startButton->setEnabled(true);
  QApplication::restoreOverrideCursor();
}

void Dialog::SendFile()
{
int bytesWrite = 0;
                       
QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"), QDir::currentPath());

QFile Sendfile(fileName);
Sendfile.open(QIODevice::ReadOnly);  

QDataStream stream( &tcpClient );

QFileInfo f(fileName);
fileName = f.fileName();
int filesize =f.size();

stream << filesize;
stream << fileName;

while(!Sendfile.atEnd())
{
    if(bytesWrite + 2048 <= filesize)
    {
        char buf[2048];
        Sendfile.read(buf, 2048);
        stream.writeRawData(buf,2048);
        bytesWrite += 2048;
       
    }
    else{
        int blocksize = filesize - bytesWrite;
        char buf[blocksize];
        Sendfile.read(buf, blocksize);
        stream.writeRawData(buf,blocksize);
       
      }
   
}

Sendfile.close();
}

void Dialog::sendToServer()
{
    QTextStream os(&tcpClient);
    os << inputText->text() << "\n";
    inputText->setText( "" );
}
[ 此贴被XChinux在2006-12-25 23:50重新编辑 ]
离线zhendeyue
只看该作者 1楼 发表于: 2006-12-30
为什么没有人回应啊。。。。。。
离线lgdwell

只看该作者 2楼 发表于: 2008-07-22
我想回应了。但是我还没写到你这块呢!如果你写好了。希望你能发给我一份,谢谢! QQ:36529790
我能!
离线ndyw

只看该作者 3楼 发表于: 2008-07-22
我也是菜鸟,不过答你一下。你的问题可能与两个函数有关:

waitForBytesWritten();
waitForReadyRead()

自己去查下assistant就知道怎么用了。

还得说句个人意见:问人问题时,最好想清楚问题的症结在那儿再问,不然别人不好帮你解决问题的。代码也不要贴得太多,只贴问题所在处就可以了。
有问题请教别人时,俺都先行谢过:)
快速回复
限100 字节
 
上一个 下一个