2
* bsocket.cpp - QSocket wrapper based on Bytestream with SRV DNS support
3
* Copyright (C) 2003 Justin Karneges
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
#include <QHostAddress>
27
//#include "safedelete.h"
29
#include "srvresolver.h"
37
#define READBUFSIZE 65536
41
class QTcpSocketSignalRelay : public QObject
45
QTcpSocketSignalRelay(QTcpSocket *sock, QObject *parent = 0)
48
qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError");
49
connect(sock, SIGNAL(hostFound()), SLOT(sock_hostFound()), Qt::QueuedConnection);
50
connect(sock, SIGNAL(connected()), SLOT(sock_connected()), Qt::QueuedConnection);
51
connect(sock, SIGNAL(disconnected()), SLOT(sock_disconnected()), Qt::QueuedConnection);
52
connect(sock, SIGNAL(readyRead()), SLOT(sock_readyRead()), Qt::QueuedConnection);
53
connect(sock, SIGNAL(bytesWritten(qint64)), SLOT(sock_bytesWritten(qint64)), Qt::QueuedConnection);
54
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(sock_error(QAbstractSocket::SocketError)), Qt::QueuedConnection);
62
void bytesWritten(qint64);
63
void error(QAbstractSocket::SocketError);
76
void sock_disconnected()
86
void sock_bytesWritten(qint64 x)
91
void sock_error(QAbstractSocket::SocketError x)
97
class BSocket::Private
107
QTcpSocketSignalRelay *qsock_relay;
117
BSocket::BSocket(QObject *parent)
121
connect(&d->ndns, SIGNAL(resultsReady()), SLOT(ndns_done()));
122
connect(&d->srv, SIGNAL(resultsReady()), SLOT(srv_done()));
133
void BSocket::reset(bool clear)
136
delete d->qsock_relay;
139
/*d->qsock->disconnect(this);
141
if(!clear && d->qsock->isOpen() && d->qsock->isValid()) {*/
142
// move remaining into the local queue
143
QByteArray block(d->qsock->bytesAvailable(), 0);
144
d->qsock->read(block.data(), block.size());
148
//d->sd.deleteLater(d->qsock);
149
d->qsock->deleteLater();
164
void BSocket::ensureSocket()
167
d->qsock = new QTcpSocket;
168
#if QT_VERSION >= 0x030200
169
d->qsock->setReadBufferSize(READBUFSIZE);
171
d->qsock_relay = new QTcpSocketSignalRelay(d->qsock);
172
connect(d->qsock_relay, SIGNAL(hostFound()), SLOT(qs_hostFound()));
173
connect(d->qsock_relay, SIGNAL(connected()), SLOT(qs_connected()));
174
connect(d->qsock_relay, SIGNAL(disconnected()), SLOT(qs_closed()));
175
connect(d->qsock_relay, SIGNAL(readyRead()), SLOT(qs_readyRead()));
176
connect(d->qsock_relay, SIGNAL(bytesWritten(qint64)), SLOT(qs_bytesWritten(qint64)));
177
connect(d->qsock_relay, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(qs_error(QAbstractSocket::SocketError)));
181
void BSocket::connectToHost(const QString &host, quint16 port)
186
d->state = HostLookup;
187
d->ndns.resolve(d->host);
190
void BSocket::connectToServer(const QString &srv, const QString &type)
193
d->state = HostLookup;
194
d->srv.resolve(srv, type, "tcp");
197
int BSocket::socket() const
200
return d->qsock->socketDescriptor();
205
void BSocket::setSocket(int s)
209
d->state = Connected;
210
d->qsock->setSocketDescriptor(s);
213
int BSocket::state() const
218
bool BSocket::isOpen() const
220
if(d->state == Connected)
226
void BSocket::close()
234
if(d->qsock->bytesToWrite() == 0)
242
void BSocket::write(const QByteArray &a)
244
if(d->state != Connected)
247
QString s = QString::fromUtf8(a);
248
fprintf(stderr, "BSocket: writing [%d]: {%s}\n", a.size(), s.latin1());
250
d->qsock->write(a.data(), a.size());
253
QByteArray BSocket::read(int bytes)
257
int max = bytesAvailable();
258
if(bytes <= 0 || bytes > max)
261
d->qsock->read(block.data(), block.size());
264
block = ByteStream::read(bytes);
267
QString s = QString::fromUtf8(block);
268
fprintf(stderr, "BSocket: read [%d]: {%s}\n", block.size(), s.latin1());
273
int BSocket::bytesAvailable() const
276
return d->qsock->bytesAvailable();
278
return ByteStream::bytesAvailable();
281
int BSocket::bytesToWrite() const
285
return d->qsock->bytesToWrite();
288
QHostAddress BSocket::address() const
291
return d->qsock->localAddress();
293
return QHostAddress();
296
quint16 BSocket::port() const
299
return d->qsock->localPort();
304
QHostAddress BSocket::peerAddress() const
307
return d->qsock->peerAddress();
309
return QHostAddress();
312
quint16 BSocket::peerPort() const
315
return d->qsock->peerPort();
320
void BSocket::srv_done()
322
if(d->srv.failed()) {
324
fprintf(stderr, "BSocket: Error resolving hostname.\n");
326
error(ErrHostNotFound);
330
d->host = d->srv.resultAddress().toString();
331
d->port = d->srv.resultPort();
333
//QTimer::singleShot(0, this, SLOT(do_connect()));
337
void BSocket::ndns_done()
339
if(!d->ndns.result().isNull()) {
340
d->host = d->ndns.resultString();
341
d->state = Connecting;
343
//QTimer::singleShot(0, this, SLOT(do_connect()));
348
fprintf(stderr, "BSocket: Error resolving hostname.\n");
350
error(ErrHostNotFound);
354
void BSocket::do_connect()
357
fprintf(stderr, "BSocket: Connecting to %s:%d\n", d->host.latin1(), d->port);
360
d->qsock->connectToHost(d->host, d->port);
363
void BSocket::qs_hostFound()
365
//SafeDeleteLock s(&d->sd);
368
void BSocket::qs_connected()
370
d->state = Connected;
372
fprintf(stderr, "BSocket: Connected.\n");
374
//SafeDeleteLock s(&d->sd);
378
void BSocket::qs_closed()
380
if(d->state == Closing)
383
fprintf(stderr, "BSocket: Delayed Close Finished.\n");
385
//SafeDeleteLock s(&d->sd);
387
delayedCloseFinished();
391
void BSocket::qs_readyRead()
393
//SafeDeleteLock s(&d->sd);
397
void BSocket::qs_bytesWritten(qint64 x64)
401
fprintf(stderr, "BSocket: BytesWritten [%d].\n", x);
403
//SafeDeleteLock s(&d->sd);
407
void BSocket::qs_error(QAbstractSocket::SocketError x)
409
if(x == QTcpSocket::RemoteHostClosedError) {
411
fprintf(stderr, "BSocket: Connection Closed.\n");
413
//SafeDeleteLock s(&d->sd);
420
fprintf(stderr, "BSocket: Error.\n");
422
//SafeDeleteLock s(&d->sd);
424
// connection error during SRV host connect? try next
425
if(d->state == HostLookup && (x == QTcpSocket::ConnectionRefusedError || x == QTcpSocket::HostNotFoundError)) {
431
if(x == QTcpSocket::ConnectionRefusedError)
432
error(ErrConnectionRefused);
433
else if(x == QTcpSocket::HostNotFoundError)
434
error(ErrHostNotFound);
439
#include "bsocket.moc"