⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 q3socket.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    }#endif#if defined(QT_CHECK_STATE)    if ( !isOpen() ) {	qWarning( "Q3Socket::writeBlock: Socket is not open" );	return -1;    }#endif#if defined(QT_CHECK_STATE)    if ( d->state == Closing ) {	qWarning( "Q3Socket::writeBlock: Cannot write, socket is closing" );    }#endif    if ( len == 0 || d->state == Closing || d->state == Idle )	return 0;    QByteArray *a = d->wba.last();    // next bit is sensitive.  if we're writing really small chunks,    // try to buffer up since system calls are expensive, and nagle's    // algorithm is even more expensive.  but if anything even    // remotely large is being written, try to issue a write at once.    bool writeNow = ( d->wsize + len >= 1400 || len > 512 );    if ( a && a->size() + len < 128 ) {	// small buffer, resize	int i = a->size();	a->resize( i+len );	memcpy( a->data()+i, data, len );    } else {	// append new buffer	a = new QByteArray( len );	memcpy( a->data(), data, len );	d->wba.append( a );    }    d->wsize += len;    if ( writeNow )	flush();    else if ( d->wsn )	d->wsn->setEnabled( true );#if defined(Q3SOCKET_DEBUG)    qDebug( "Q3Socket (%s): writeBlock %d bytes", name(), (int)len );#endif    return len;}/*!    Reads a single byte/character from the internal read buffer.    Returns the byte/character read, or -1 if there is nothing to be    read.    \sa bytesAvailable(), putch()*/int Q3Socket::getch(){    if ( isOpen() && d->rba.size() > 0 ) {	uchar c;	d->rba.consumeBytes( 1, (char*)&c );	// After we read data from our internal buffer, if we use the	// setReadBufferSize() to limit our buffer, we might now be able to	// read more data in our buffer. So enable the read socket notifier,	// but do this only if we are not in a slot connected to the	// readyRead() signal since this might cause a bad recursive behavior.	// We can test for this condition by looking at the	// sn_read_alreadyCalled flag.	if ( d->rsn && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) == -1 )	    d->rsn->setEnabled( true );	return c;    }    return -1;}/*!    Writes the character \a ch to the output buffer.    Returns \a ch, or -1 if an error occurred.    \sa getch()*/int Q3Socket::putch( int ch ){    char buf[2];    buf[0] = ch;    return writeBlock(buf, 1) == 1 ? ch : -1;}/*!    This implementation of the virtual function QIODevice::ungetch()    prepends the character \a ch to the read buffer so that the next    read returns this character as the first character of the output.*/int Q3Socket::ungetch( int ch ){#if defined(QT_CHECK_STATE)    if ( !isOpen() ) {	qWarning( "Q3Socket::ungetch: Socket not open" );	return -1;    }#endif    return d->rba.ungetch( ch );}/*!    Returns true if it's possible to read an entire line of text from    this socket at this time; otherwise returns false.    Note that if the peer closes the connection unexpectedly, this    function returns false. This means that loops such as this won't    work:    \code	while( !socket->canReadLine() ) // WRONG	    ;    \endcode    \sa readLine()*/bool Q3Socket::canReadLine() const{    if ( ((Q3Socket*)this)->d->rba.scanNewline( 0 ) )	return true;    return ( bytesAvailable() > 0 &&	     (((Q3Socket*)this)->d->rba.scanNewline( 0 ) || QIODevice::canReadLine()) );}/*!  \internal    Internal slot for handling socket read notifications.    This function has can usually only be entered once (i.e. no    recursive calls). If the argument \a force is true, the function    is executed, but no readyRead() signals are emitted. This    behaviour is useful for the waitForMore() function, so that it is    possible to call waitForMore() in a slot connected to the    readyRead() signal.*/void Q3Socket::sn_read( bool force ){    Q_LONG maxToRead = 0;    if ( d->readBufferSize > 0 ) {	maxToRead = d->readBufferSize - d->rba.size();	if ( maxToRead <= 0 ) {	    if ( d->rsn )		d->rsn->setEnabled( false );	    return;	}    }    // Use Q3SocketPrivate::sn_read_alreadyCalled to avoid recursive calls of    // sn_read() (and as a result avoid emitting the readyRead() signal in a    // slot for readyRead(), if you use bytesAvailable()).    if ( !force && Q3SocketPrivate::sn_read_alreadyCalled.findRef(this) != -1 )	return;    Q3SocketPrivate::sn_read_alreadyCalled.append( this );    char buf[4096];    Q_LONG nbytes = d->socket->bytesAvailable();    Q_LONG nread;    QByteArray *a = 0;    if ( state() == Connecting ) {	if ( nbytes > 0 ) {	    tryConnection();	} else {	    // nothing to do, nothing to care about	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );	    return;	}    }    if ( state() == Idle ) {	Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );	return;    }    if ( nbytes <= 0 ) {			// connection closed?	// On Windows this may happen when the connection is still open.	// This happens when the system is heavily loaded and we have	// read all the data on the socket before a new WSAAsyncSelect	// event is processed. A new read operation would then block.	// This code is also useful when Q3Socket is used without an	// event loop.	nread = d->socket->readBlock( buf, maxToRead ? QMIN((Q_LONG)sizeof(buf),maxToRead) : sizeof(buf) );	if ( nread == 0 ) {			// really closed            if ( !d->socket->isOpen() ) {#if defined(Q3SOCKET_DEBUG)                qDebug( "Q3Socket (%s): sn_read: Connection closed", name() );#endif                d->connectionClosed();                emit connectionClosed();            }	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );	    return;	} else {	    if ( nread < 0 ) {		if ( d->socket->error() == Q3SocketDevice::NoError ) {		    // all is fine		    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );		    return;		}#if defined(Q3SOCKET_DEBUG)		qWarning( "Q3Socket::sn_read (%s): Close error", name() );#endif		if ( d->rsn )		    d->rsn->setEnabled( false );		emit error( ErrSocketRead );		Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );		return;	    }	    a = new QByteArray( nread );	    memcpy( a->data(), buf, nread );	}    } else {					// data to be read#if defined(Q3SOCKET_DEBUG)	qDebug( "Q3Socket (%s): sn_read: %ld incoming bytes", name(), nbytes );#endif	if ( nbytes > (int)sizeof(buf) ) {	    // big	    a = new QByteArray( nbytes );	    nread = d->socket->readBlock( a->data(), maxToRead ? QMIN(nbytes,maxToRead) : nbytes );	} else {	    a = 0;	    nread = d->socket->readBlock( buf, maxToRead ? QMIN((Q_LONG)sizeof(buf),maxToRead) : sizeof(buf) );	    if ( nread > 0 ) {		// ##### could setRawData		a = new QByteArray( nread );		memcpy( a->data(), buf, nread );	    }	}	if ( nread == 0 ) {#if defined(Q3SOCKET_DEBUG)	    qDebug( "Q3Socket (%s): sn_read: Connection closed", name() );#endif	    // ### we should rather ask the socket device if it is closed	    d->connectionClosed();	    emit connectionClosed();	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );            delete a;	    return;	} else if ( nread < 0 ) {            delete a;	    if ( d->socket->error() == Q3SocketDevice::NoError ) {		// all is fine		Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );		return;	    }#if defined(QT_CHECK_RANGE)	    qWarning( "Q3Socket::sn_read: Read error" );#endif	    if ( d->rsn )		d->rsn->setEnabled( false );	    emit error( ErrSocketRead );	    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );	    return;	}	if ( nread != (int)a->size() ) {		// unexpected#if defined(CHECK_RANGE) && !defined(Q_OS_WIN32)	    qWarning( "Q3Socket::sn_read: Unexpected short read" );#endif	    a->resize( nread );	}    }    d->rba.append( a );    if ( !force ) {	if ( d->rsn )	    d->rsn->setEnabled( false );	emit readyRead();	if ( d->rsn )	    d->rsn->setEnabled( true );    }    Q3SocketPrivate::sn_read_alreadyCalled.removeRef( this );}/*!  \internal    Internal slot for handling socket write notifications.*/void Q3Socket::sn_write(){    if ( d->state == Connecting )		// connection established?	tryConnection();    flush();}void Q3Socket::emitErrorConnectionRefused(){    emit error( ErrConnectionRefused );}void Q3Socket::tryConnection(){    if ( d->socket->connect( d->addr, d->port ) ) {	d->state = Connected;#if defined(Q3SOCKET_DEBUG)	qDebug( "Q3Socket (%s): sn_write: Got connection to %s",		name(), peerName().ascii() );#endif	if ( d->rsn )	    d->rsn->setEnabled( true );	emit connected();    } else {	d->state = Idle;	QTimer::singleShot( 0, this, SLOT(emitErrorConnectionRefused()) );	return;    }}/*!    Returns the socket number, or -1 if there is no socket at the moment.*/int Q3Socket::socket() const{    if ( d->socket == 0 )	return -1;    return d->socket->socket();}/*!    Sets the socket to use \a socket and the state() to \c Connected.    The socket must already be connected.    This allows us to use the Q3Socket class as a wrapper for other    socket types (e.g. Unix Domain Sockets).*/void Q3Socket::setSocket( int socket ){    setSocketIntern( socket );    d->state = Connection;    d->rsn->setEnabled( true );}/*!    Sets the socket to \a socket. This is used by both setSocket() and    connectToHost() and can also be used on unconnected sockets.*/void Q3Socket::setSocketIntern( int socket ){    if ( state() != Idle ) {	clearPendingData();        close();    }    Q_ULONG oldBufferSize = d ? d->readBufferSize : 0;    delete d;    d = new Q3SocketPrivate;    if (oldBufferSize)        d->readBufferSize = oldBufferSize;    if ( socket >= 0 ) {	Q3SocketDevice *sd = new Q3SocketDevice( socket, Q3SocketDevice::Stream );	sd->setBlocking( false );	sd->setAddressReusable( true );	d->setSocketDevice( this, sd );    }    d->state = Idle;    // Initialize the IO device flags    resetStatus();    open( IO_ReadWrite );    // hm... this is not very nice.    d->host.clear();    d->port = 0;#ifndef QT_NO_DNS    delete d->dns4;    d->dns4 = 0;    delete d->dns6;    d->dns6 = 0;#endif}/*!    Returns the host port number of this socket, in native byte order.*/Q_UINT16 Q3Socket::port() const{    if ( d->socket == 0 )	return 0;    return d->socket->port();}/*!    Returns the peer's host port number, normally as specified to the    connectToHost() function. If none has been set, this function    returns 0.    Note that Qt always uses native byte order, i.e. 67 is 67 in Qt;    there is no need to call htons().*/Q_UINT16 Q3Socket::peerPort() const{    if ( d->socket == 0 )	return 0;    return d->socket->peerPort();}/*!    Returns the host address of this socket. (This is normally the    main IP address of the host, but can be e.g. 127.0.0.1 for    connections to localhost.)*/QHostAddress Q3Socket::address() const{    if ( d->socket == 0 ) {	QHostAddress tmp;	return tmp;    }    return d->socket->address();}/*!    Returns the address of the connected peer if the socket is in    Connected state; otherwise an empty QHostAddress is returned.*/QHostAddress Q3Socket::peerAddress() const{    if ( d->socket == 0 ) {	QHostAddress tmp;	return tmp;    }    return d->socket->peerAddress();}/*!    Returns the host name as specified to the connectToHost()    function. An empty string is returned if none has been set.*/QString Q3Socket::peerName() const{    return d->host;}/*!    Sets the size of the Q3Socket's internal read buffer to \a bufSize.    Usually Q3Socket reads all data that is available from the operating    system's socket. If the buffer size is limited to a certain size, this    means that the Q3Socket class doesn't buffer more than this size of data.    If the size of the read buffer is 0, the read buffer is unlimited and all    incoming data is buffered. This is the default.    If you read the data in the readyRead() signal, you shouldn't use this    option since it might slow down your program unnecessary. This option is    useful if you only need to read the data at certain points in time, like in    a realtime streaming application.    \sa readBufferSize()*/void Q3Socket::setReadBufferSize( Q_ULONG bufSize ){    d->readBufferSize = bufSize;}/*!    Returns the size of the read buffer.    \sa setReadBufferSize()*/Q_ULONG Q3Socket::readBufferSize() const{    return d->readBufferSize;}/*!    \fn bool Q3Socket::isSequential() const    \internal*/#endif //QT_NO_NETWORK

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -