• 9673阅读
  • 4回复

QTcpSocket只能传输8K大小的文件 [复制链接]

上一主题 下一主题
离线hats1987
 

只看楼主 倒序阅读 楼主  发表于: 2011-03-08

发送方代码:
  1.    QFile file("test.txt");
  2.     file.open(QIODevice::ReadWrite);
  3.     char* data = new char[MAX_SIZE];
  4.     qint64 readed = file.read(data,MAX_SIZE);
  5.     file.close();
  6.     this->socket->write(data,readed);
  7.     delete []data;


服务器方接受到数据,然后新建个文件,把数据写进去。
奇怪的是服务器端接收的文件大小最多就8K,这个要怎么解决?
Qt 5.3.2
Win XP/7:  VC2010/ VC6 /Gcc 4.9.2
离线lclflash

只看该作者 1楼 发表于: 2011-03-08
你应该是边读边发送,最好用QFile的map函数作文件映射然后再发送,还有就是write的时候要检查一下返回值,看看是不是都发送完成 否则循环发送。
离线aeo153

只看该作者 2楼 发表于: 2011-05-03
看例子
发送时数据包头记录数据包的大小
void Server::sendFortune()
{
//! [5]
    QByteArray block;
    QDataStream out(&block, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_4_0);
//! [4] //! [6]
    out << (quint16)0;
    out << fortunes.at(qrand() % fortunes.size());
    out.device()->seek(0);
    out << (quint16)(block.size() - sizeof(quint16));
//! [6] //! [7]



接收数据包时当接收到的数据等于数据包的大小时,才真正去获取数据
void Client::readFortune()
{
//! [9]
    QDataStream in(tcpSocket);
    in.setVersion(QDataStream::Qt_4_0);

    if (blockSize == 0) {
        if (tcpSocket->bytesAvailable() < (int)sizeof(quint16))
            return;
//! [8]

//! [10]
        in >> blockSize;
    }

    if (tcpSocket->bytesAvailable() < blockSize)
        return;
//! [10] //! [11]

    QString nextFortune;
    in >> nextFortune;

    if (nextFortune == currentFortune) {
        QTimer::singleShot(0, this, SLOT(requestNewFortune()));
        return;
    }
离线edsionte
只看该作者 3楼 发表于: 2011-05-11
数据大小不能超过socket缓冲区大小
分开发。
离线oscarboycn

只看该作者 4楼 发表于: 2011-06-28
qint64 QNativeSocketEnginePrivate::nativeWrite(const char *data, qint64 len)
{
    Q_Q(QNativeSocketEngine);
    qint64 ret = 0;
    // don't send more than 49152 per call to WSASendTo to avoid getting a WSAENOBUFS
    for (;;) {
        qint64 bytesToSend = qMin<qint64>(49152, len - ret);
        WSABUF buf;
        buf.buf = (char*)data + ret;
        buf.len = bytesToSend;
        DWORD flags = 0;
        DWORD bytesWritten = 0;

        int socketRet = ::WSASend(socketDescriptor, &buf, 1, &bytesWritten, flags, 0,0);

        ret += qint64(bytesWritten);

        if (socketRet != SOCKET_ERROR) {
            if (ret == len)
                break;
            else
                continue;
        } else if (WSAGetLastError() == WSAEWOULDBLOCK) {
            break;
        } else {
            int err = WSAGetLastError();
            WS_ERROR_DEBUG(err);
            switch (err) {
            case WSAECONNRESET:
            case WSAECONNABORTED:
                ret = -1;
                setError(QAbstractSocket::NetworkError, WriteErrorString);
                q->close();
                break;
            default:
                break;
            }
            break;
        }
    }

源代码中限制了发送的大小,如果数据过大过多,可能未来得及将剩余数据刷新,故需要调用flush()函数--可能不止调用一次,才能将剩余的数据发送出去(视剩余数据大小来定)
http://www.21ic.com
http://bbs.eetop.cn
http://www.eetop.cn/
http://www.eet-china.com/
http://www.netyi.net/
http://www.pcbbbs.com/
http://www.pcbtech.net/
快速回复
限100 字节
 
上一个 下一个