• 7692阅读
  • 2回复

请教 QT TCPSOCKET 传送大批数据不成功,附源码 [复制链接]

上一主题 下一主题
离线lay_liu
 
只看楼主 倒序阅读 楼主  发表于: 2009-11-16
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
本人想做个网络传输的模块,客户端分多次传送大的文件,使用readyRead ,  bytesWrite信号,收到的数据总是不完整,希望能指点一二,如何实现我想要的大文件多次传送功能。跪谢中。。。。。。
具体实现如下:
//启动服务器
void NetServer::startServer(QHostAddress ip,int port)
{
    int datport=port+1;

    pcmdServer->listen(ip,port);
    connect(pcmdServer,SIGNAL(newConnection()),this,SLOT(cmdReceiver()));

    pdatServer->listen(ip,datport);
    connect(pdatServer,SIGNAL(newConnection()),this,SLOT(datReceiver()));

//    connect(this->pdatsendSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(datWriteData(qint64)));

}
//接收链接
void NetServer::datReceiver()
{
    if(pdatServer->hasPendingConnections())
    {
        pdatReadSocket=pdatServer->nextPendingConnection();
    }
    memset(m_datBuf,0,MAXBUFLEN);
    lcurdataLen=0;
    connect(pdatReadSocket,SIGNAL(readyRead()),this,SLOT(datRead()));
    connect(pdatReadSocket,SIGNAL(disconnected()),pdatReadSocket,SLOT(deleteLater()));

}

//读数据
void NetServer::datRead()
{
  //  QString str(pdatBuf);
  //  QMessageBox::information(NULL,"",str);

    if(pdatReadSocket==NULL || ldataLen<=0)
        return ;

    int nrealLen=pdatReadSocket->read(pdatBuf,1024);
    if((lcurdataLen+nrealLen)<ldataLen)
    {
        memcpy((char *)(&m_datBuf[lcurdataLen]),pdatBuf,nrealLen);
        lcurdataLen+=nrealLen;
    }
    else
    {
        memcpy((char *)(&m_datBuf[lcurdataLen]),pdatBuf,(ldataLen-lcurdataLen));
        pdatReadSocket->disconnectFromHost();
        pdatReadSocket=NULL;
        lcurdataLen=0;
    }

}

//发送数据void
NetServer::sendDat(QHostAddress remoteip,int port,char * pdat,int len)
{
/*
    pdatsendSocket->connectToHost(remoteip,port);
    if(pdatsendSocket->waitForConnected(200))
    {
        pdatsendSocket->write(pdat,len);
        pdatsendSocket->disconnectFromHost();
    }
*/

    pdatsendSocket->connectToHost(remoteip,port);
    if(pdatsendSocket->waitForConnected(2000)==false)
    {
        return ;
    }

    connect(pdatsendSocket,SIGNAL(bytesWritten(qint64)),this,SLOT(datWriteData(qint64)));

    //sendThread *pst=new sendThread(pdatsendSocket,pdat,len,this);
    //connect(pst,SIGNAL(finished()),pst,SLOT(deleteLater()));
    //pst->start();
    //pcmdsendSocket->write(pcmd,len);
    //pcmdsendSocket->disconnectFromHost();
    //pcmdsendSocket->waitForDisconnected();

    this->pdatWrite=pdat;
    this->ldatWriteLen=len;
    nLeave=ldatWriteLen;
    nHasSend=0;
    if(nLeave>=1024)
    {
        pdatsendSocket->write((char *)(pdat+nHasSend),1024);
        //pdatsendSocket->waitForBytesWritten(20000);
    }
    else
    {
        pdatsendSocket->write((char *)(pdat+nHasSend),nLeave);
        //pdatsendSocket->waitForBytesWritten(20000);
    }
//   while(nLeave>0)
  //  {
  //      usleep(100000);
  //  }

}

void NetServer::datWriteData(qint64 haswriteNum)
{

    nLeave-=haswriteNum;
    nHasSend+=haswriteNum;
    emit this->progressWrite(nHasSend);

    if(nLeave<=0)
    {
         pdatsendSocket->disconnectFromHost();
         pdatsendSocket->waitForDisconnected(20000);
        return ;
    }
    if((ldatWriteLen-nHasSend)>=1024)
    {
        if(pdatsendSocket->write((char *)(pdatWrite+nHasSend),1024)<0)
        {
            emit error(pdatsendSocket->error());
            QMessageBox::information(NULL,"",pdatsendSocket->errorString());
            nLeave=0;
            return;
        }
        //pdatsendSocket->waitForBytesWritten(20000);
         emit this->progressWrite(nHasSend);
    }
    else
    {

        if(pdatsendSocket->write((char *)(pdatWrite+nHasSend),nLeave)<0)
        {
            emit error(pdatsendSocket->error());
            QMessageBox::information(NULL,"",pdatsendSocket->errorString());
            nLeave=0;
            return;
        }
        //pdatsendSocket->waitForBytesWritten(20000);
        emit this->progressWrite(nHasSend);
    }

}

离线hover_sky

只看该作者 1楼 发表于: 2009-11-17
客户端分块发送

服务器全部收完了,组合在一起,再显示
离线genshing
只看该作者 2楼 发表于: 2009-11-17
TCP封包有大小限制的
快速回复
限100 字节
 
上一个 下一个