Beispiel #1
0
QStringList
QuasarSocket::recv(int timeout)
{
    int timeoutCnt = 0;

    while (true) {
	char buffer[8192];
	int count = readBlock(buffer, 8191);
	if (count == -1) {
	    QStringList results;
	    results.push_back("error:");
	    results.push_back("Error reading from server");
	    return results;
	}
	if (count == 0) {
	    waitForMore(1000);
	    if (++timeoutCnt < timeout || timeout == 0) continue;

	    QStringList results;
	    results.push_back("error:");
	    results.push_back("Timeout reading from server");
	    return results;
	}

	buffer[count] = 0;
	_readLine += QString::fromUtf8(buffer);
	timeoutCnt = 0;

	QString data;
	if (_readLine.left(1) == "\002") {
	    int index = _readLine.find('\003');
	    if (index == -1) continue;

	    data = _readLine.mid(1, index - 1);
	    _readLine = _readLine.mid(index + 1);
	} else {
	    int index = _readLine.find('\n');
	    if (index == -1) continue;

	    data = _readLine.left(index);
	    _readLine = _readLine.mid(index + 1);

	    while (data.right(1) == "\r")
		data = data.left(data.length() - 1);
	}

	return TclObject(data).toStringList();
    }

    return QStringList();
}
Beispiel #2
0
Q_ULONG Q3Socket::waitForMore( int msecs ) const
{
    return waitForMore( msecs, 0 );
}
Beispiel #3
0
/*!
    Writes \a len bytes to the socket from \a data and returns the
    number of bytes written. Returns -1 if an error occurred.

    This is used for MSocketDevice::Stream sockets.
*/
qint64 MSocketDevice::writeData( const char *data, qint64 len )
{
    if ( len == 0 )
        return 0;

    if ( data == 0 ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::writeBlock: Null pointer error");
        return -1;
    }
    if ( !isValid() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::writeBlock: Invalid socket");
        return -1;
    }
    if ( !isOpen() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::writeBlock: Device is not open");
        return -1;
    }
    if ( !isWritable() ) {
        VERBOSE(VB_SOCKET|VB_EXTRA,
                "MSocketDevice::writeBlock: Write operation not permitted");
        return -1;
    }
    bool done = false;
    int r = 0;
    bool timeout;
    while ( !done ) {
	r = ::write( fd, data, len );
	done = true;
	if ( r < 0 && e == NoError &&
	     errno != EAGAIN && errno != EWOULDBLOCK ) {
	    switch( errno ) {
	    case EINTR: // signal - call read() or whatever again
		done = false;
		break;
	    case EPIPE:
            case ECONNRESET:
		// connection closed
		close();
		r = 0;
		break;
	    case ENOSPC:
	    case EIO:
	    case EISDIR:
	    case EBADF:
	    case EINVAL:
	    case EFAULT:
	    case ENOTCONN:
	    case ENOTSOCK:
		e = Impossible;
		break;
#if defined(ENONET)
	    case ENONET:
#endif
	    case EHOSTUNREACH:
	    case ENETDOWN:
	    case ENETUNREACH:
	    case ETIMEDOUT:
		e = NetworkFailure;
		break;
	    default:
		e = UnknownError;
		break;
	    }
	} else if ( waitForMore( 0, &timeout ) == 0 ) {
	    if ( !timeout ) {
		// connection closed
		close();
	    }
	}
    }
    return r;
}
Beispiel #4
0
bool MythSocket::readStringList(QStringList &list, uint timeoutMS)
{
    list.clear();

    if (state() != Connected)
    {
        VERBOSE(VB_IMPORTANT, LOC +
                "readStringList: Error, called with unconnected socket.");
        return false;
    }

    MythTimer timer;
    timer.start();
    int elapsed = 0;

    while (waitForMore(5) < 8)
    {
        elapsed = timer.elapsed();
        if (elapsed >= (int)timeoutMS)
        {
            VERBOSE(VB_IMPORTANT, LOC + "readStringList: " +
                    QString("Error, timed out after %1 ms.").arg(timeoutMS));
            close();
            return false;
        }

        if (state() != Connected)
        {
            VERBOSE(VB_IMPORTANT, LOC +
                    "readStringList: Connection died.");
            return false;
        }

        {
            struct timeval tv;
            int maxfd;
            fd_set rfds;

            FD_ZERO(&rfds);
            FD_SET(socket(), &rfds);
            maxfd = socket();

            tv.tv_sec = 0;
            tv.tv_usec = 0;

            int rval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
            if (rval)
            {
                if (bytesAvailable() == 0)
                {
                    VERBOSE(VB_IMPORTANT, LOC +
                            "readStringList: Connection died (select).");
                    return false;
                }
            }
        }
    }

    QByteArray sizestr(8 + 1, '\0');
    if (readBlock(sizestr.data(), 8) < 0)
    {
        VERBOSE(VB_GENERAL, LOC +
                QString("readStringList: Error, readBlock return error (%1)")
                .arg(errorToString()));
        close();
        return false;
    }

    QString sizes = sizestr;
    qint64 btr = sizes.trimmed().toInt();

    if (btr < 1)
    {
        int pending = bytesAvailable();
        QByteArray dump(pending + 1, 0);
        readBlock(dump.data(), pending);
        VERBOSE(VB_IMPORTANT, LOC +
                QString("Protocol error: '%1' is not a valid size "
                        "prefix. %2 bytes pending.")
                        .arg(sizestr.data()).arg(pending));
        return false;
    }

    QByteArray utf8(btr + 1, 0);

    qint64 read = 0;
    int errmsgtime = 0;
    timer.start();

    while (btr > 0)
    {
        qint64 sret = readBlock(utf8.data() + read, btr);
        if (sret > 0)
        {
            read += sret;
            btr -= sret;
            if (btr > 0)
            {
                timer.start();
            }
        }
        else if (sret < 0 && error() != MSocketDevice::NoError)
        {
            VERBOSE(VB_GENERAL, LOC +
                    QString("readStringList: Error, readBlock %1")
                    .arg(errorToString()));
            close();
            return false;
        }
        else if (!isValid())
        {
            VERBOSE(VB_IMPORTANT, LOC +
                    "readStringList: Error, socket went unconnected");
            close();
            return false;
        }
        else
        {
            elapsed = timer.elapsed();
            if (elapsed  > 10000)
            {
                if ((elapsed - errmsgtime) > 10000)
                {
                    errmsgtime = elapsed;
                    VERBOSE(VB_GENERAL, LOC +
                            QString("readStringList: Waiting for data: %1 %2")
                            .arg(read).arg(btr));
                }
            }

            if (elapsed > 100000)
            {
                VERBOSE(VB_GENERAL, LOC +
                        "Error, readStringList timeout (readBlock)");
                return false;
            }

            usleep(500);
        }
    }

    QString str = QString::fromUtf8(utf8.data());

    QByteArray payload;
    payload = payload.setNum(str.length());
    payload += "        ";
    payload.truncate(8);
    payload += str;

    if (VERBOSE_LEVEL_CHECK(VB_NETWORK))
    {
        QString msg = QString("read  <- %1 %2").arg(socket(), 2)
            .arg(payload.data());

        if (!VERBOSE_LEVEL_CHECK(VB_EXTRA) && msg.length() > 88)
        {
            msg.truncate(85);
            msg += "...";
        }
        VERBOSE(VB_NETWORK, LOC + msg);
    }

    list = str.split("[]:[]");

    m_notifyread = false;
    s_readyread_thread->WakeReadyReadThread();
    return true;
}