void QSocket::setSocketIntern( int socket ) { if ( state() != Idle ) { clearPendingData(); close(); } Q_ULONG oldBufferSize = d ? d->readBufferSize : 0; delete d; d = new QSocketPrivate; if (oldBufferSize) d->readBufferSize = oldBufferSize; if ( socket >= 0 ) { QSocketDevice *sd = new QSocketDevice( socket, QSocketDevice::Stream ); sd->setBlocking( FALSE ); sd->setAddressReusable( TRUE ); d->setSocketDevice( this, sd ); } d->state = Idle; // Initialize the IO device flags setFlags( IO_Direct ); resetStatus(); open( IO_ReadWrite ); // hm... this is not very nice. d->host = QString::null; d->port = 0; #ifndef QT_NO_DNS delete d->dns4; d->dns4 = 0; delete d->dns6; d->dns6 = 0; #endif }
void QSocketPrivate::setSocketDevice( QSocket *q, QSocketDevice *device ) { delete socket; delete rsn; delete wsn; if ( device ) { socket = device; } else { socket = new QSocketDevice( QSocketDevice::Stream, ( addr.isIPv4Address() ? QSocketDevice::IPv4 : QSocketDevice::IPv6 ), 0 ); socket->setBlocking( FALSE ); socket->setAddressReusable( TRUE ); } rsn = new QSocketNotifier( socket->socket(), QSocketNotifier::Read, q, "read" ); wsn = new QSocketNotifier( socket->socket(), QSocketNotifier::Write, q, "write" ); QObject::connect( rsn, SIGNAL(activated(int)), q, SLOT(sn_read()) ); rsn->setEnabled( FALSE ); QObject::connect( wsn, SIGNAL(activated(int)), q, SLOT(sn_write()) ); wsn->setEnabled( FALSE ); }
/*! \internal Writes \a len bytes to the socket from \a data and returns the number of bytes written. Returns -1 if an error occurred. */ Q_LONG cAsyncNetIOPrivate::writeBlock( const char* data, Q_ULONG len ) { // Invalid Socket -> Disconnected if ( !socket->isValid() ) { socket->close(); return 0; } if ( len == 0 ) return 0; QByteArray* a = wba.last(); 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 ); wba.append( a ); } wsize += len; return len; }
void send(QSocketDevice& socket, const QString& type, const QStringList& args, bool debug) { TclObject list; list.lappend(type); for (unsigned int i = 0; i < args.size(); ++i) list.lappend(args[i]); if (debug) logDebug("send: " + list.toString()); QString message = list.toString(); if (message.contains('\n')) message = "\002" + message + "\003"; else message += "\n"; QCString data = message.utf8(); int len = data.length(); int pos = 0; while (pos < len) { int count = socket.writeBlock(data.data() + pos, len - pos); socket.flush(); if (count == -1) { logError("writeBlock error: %d", errno); exit(4); } pos += count; } }
void Server::newConnection(int socket){ cout << "New connection received" << endl; QSocketDevice* s = new QSocketDevice(); s->setSocket(socket, QSocketDevice::Stream); int use_keep_alive = 1; if(setsockopt(socket, SOL_SOCKET, SO_KEEPALIVE, &use_keep_alive, sizeof(use_keep_alive))){ int errsv = errno; cerr << "Unable to set socket to use keep_alive error: " << errsv << " : " << strerror(errsv) << endl; exit(1); } // change the default behaviour to a more aggressive polling struct protoent* pe = getprotobyname("tcp"); // pe->p_proto contains the number int keep_alive_time = 60; int keep_alive_intvl = 60; int keep_alive_probes = 20; if(setsockopt(socket, pe->p_proto, TCP_KEEPIDLE, &keep_alive_time, sizeof(keep_alive_time))) cerr << "Unable to set socket option keep alive time" << endl; if(setsockopt(socket, pe->p_proto, TCP_KEEPINTVL, &keep_alive_intvl, sizeof(keep_alive_intvl))) cerr << "Unable to set socket option keep alive interval" << endl; if(setsockopt(socket, pe->p_proto, TCP_KEEPCNT, &keep_alive_probes, sizeof(keep_alive_probes))) cerr << "Unable to set sockt option keep alive probes" << endl; connections[s] = new ConnectionObject(s, &pSet, (QWidget*)this); }
void QSocketPrivate::closeSocket() { // Order is important here - the socket notifiers must go away // before the socket does, otherwise libc or the kernel will // become unhappy. delete rsn; rsn = 0; delete wsn; wsn = 0; if ( socket ) socket->close(); }
void mainLoop(QSocketDevice& socket, bool debug) { CommandProcessor processor; QString data; bool done = false; while (!done) { int timeout = -1; if (processor.waitingForResults()) timeout = 50; // TODO: different timeout if using POS and not ping bool wasTimeout = false; int result = socket.waitForMore(timeout, &wasTimeout); if (socket.atEnd() && result == 0 && !wasTimeout) break; if (result == -1) { logError("waitForMore error: %d", errno); break; } if (processor.waitingForResults() && processor.resultsAvailable()) { QString type; QStringList results; processor.getResults(type, results); send(socket, type, results, debug); } if (wasTimeout) continue; char buffer[result + 1]; result = socket.readBlock(buffer, result); if (result == -1) { logError("readBlock error: %d", errno); break; } buffer[result] = 0; data += QString::fromUtf8(buffer); while (true) { QString line; if (data.left(1) == "\002") { int index = data.find('\003'); if (index == -1) break; line = data.mid(1, index - 1); data = data.mid(index + 1); } else { int index = data.find('\n'); if (index == -1) break; line = data.left(index); data = data.mid(index + 1); while (line.right(1) == "\r") line = line.left(line.length() - 1); } if (line.isEmpty()) continue; if (debug) logDebug("recv: " + line); if (line == "ping") { send(socket, "ping:", "pong", debug); } else if (line == "quit" || line == "exit") { done = true; } else { processor.processCommand(line); if (processor.resultsAvailable()) { QString type; QStringList results; processor.getResults(type, results); send(socket, type, results, debug); } } } } }