Skip to content

Commit

Permalink
libdeng2: Improved Socket opening, added better Address constructor
Browse files Browse the repository at this point in the history
Sockets can now be opened asynchronously, with a signal emitted when
the connection is open.
  • Loading branch information
skyjake committed Jan 25, 2013
1 parent 6b3b005 commit a809df1
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 12 deletions.
2 changes: 2 additions & 0 deletions doomsday/libdeng2/include/de/net/address.h
Expand Up @@ -48,6 +48,8 @@ class DENG2_PUBLIC Address : public LogEntry::Arg::Base
*/
Address(QHostAddress const &address, duint16 port = 0);

Address(String const &addressWithOptionalPort);

Address(char const *address, duint16 port = 0);

Address(Address const &other);
Expand Down
4 changes: 2 additions & 2 deletions doomsday/libdeng2/include/de/net/protocol.h
Expand Up @@ -68,7 +68,7 @@ class DENG2_PUBLIC Protocol
*
* @return Specialized Packet, or @c NULL.
*/
typedef Packet* (*Constructor)(Block const &);
typedef Packet *(*Constructor)(Block const &);

/// Reply types. @see reply()
enum Reply {
Expand All @@ -80,7 +80,7 @@ class DENG2_PUBLIC Protocol
public:
Protocol();

~Protocol();
virtual ~Protocol();

/**
* Registers a new constructor function.
Expand Down
13 changes: 12 additions & 1 deletion doomsday/libdeng2/include/de/net/socket.h
Expand Up @@ -71,6 +71,8 @@ class DENG2_PUBLIC Socket : public QObject, public Transmitter
Q_DECLARE_FLAGS(HeaderFlags, HeaderFlag)

public:
Socket();

/**
* Opens a socket to @a address and waits (blocks) until the connection has
* been formed. The socket is ready to be used after the constructor
Expand All @@ -80,7 +82,15 @@ class DENG2_PUBLIC Socket : public QObject, public Transmitter
* @param address Address to connect to.
* @param timeOut Maximum time to wait for connection.
*/
Socket(Address const &address, TimeDelta const &timeOut = 5);
Socket(Address const &address, TimeDelta const &timeOut);

/**
* Opens a connection to @a address and returns immediately. The
* connected() signal is emitted when the connection is ready to use.
*
* @param address Address to connect to.
*/
void connect(Address const &address);

virtual ~Socket();

Expand Down Expand Up @@ -165,6 +175,7 @@ class DENG2_PUBLIC Socket : public QObject, public Transmitter
void close();

signals:
void connected();
void messagesReady();
void connectionFailure();
void disconnected();
Expand Down
2 changes: 1 addition & 1 deletion doomsday/libdeng2/src/legacy/legacynetwork.cpp
Expand Up @@ -99,7 +99,7 @@ int LegacyNetwork::open(Address const &address)
LOG_AS("LegacyNetwork::open");
try
{
Socket *sock = new Socket(address);
Socket *sock = new Socket(address, 5.0 /* seconds for timeout */);
int id = d->nextId();
d->sockets.insert(id, sock);
return id;
Expand Down
21 changes: 20 additions & 1 deletion doomsday/libdeng2/src/net/address.cpp
Expand Up @@ -42,6 +42,25 @@ Address::Address(QHostAddress const &host, duint16 port)
: _host(host), _port(port)
{}

Address::Address(String const &addressWithOptionalPort) : _port(0)
{
String str = addressWithOptionalPort;
if(str.contains(':'))
{
int pos = str.indexOf(':');
_port = str.mid(pos + 1).toInt();
str = str.left(pos);
}
if(str == "localhost")
{
_host = QHostAddress(QHostAddress::LocalHost);
}
else
{
_host = QHostAddress(str);
}
}

Address::Address(Address const &other)
: LogEntry::Arg::Base(), _host(other._host), _port(other._port)
{}
Expand All @@ -58,7 +77,7 @@ bool Address::matches(Address const &other, duint32 mask)

String Address::asText() const
{
String result = _host.toString();
String result = (_host == QHostAddress::LocalHost? "localhost" : _host.toString());
if(_port)
{
result += ":" + QString::number(_port);
Expand Down
4 changes: 3 additions & 1 deletion doomsday/libdeng2/src/net/message.cpp
Expand Up @@ -19,7 +19,7 @@

#include "de/Message"

using namespace de;
namespace de {

Message::Message(IByteArray const &other) : Block(other), _channel(0)
{}
Expand All @@ -35,3 +35,5 @@ Message::Message(Address const &addr, Channel channel, IByteArray const &other)
Message::Message(Address const &addr, Channel channel, IByteArray const &other, Offset at, Size count)
: Block(other, at, count), _address(addr), _channel(channel)
{}

} // namespace de
33 changes: 27 additions & 6 deletions doomsday/libdeng2/src/net/socket.cpp
Expand Up @@ -366,7 +366,16 @@ struct Socket::Instance
}
};

Socket::Socket(Address const &address, TimeDelta const &timeOut)
Socket::Socket()
{
d = new Instance;
d->socket = new QTcpSocket;
initialize();

QObject::connect(d->socket, SIGNAL(connected()), this, SIGNAL(connected()));
}

Socket::Socket(Address const &address, TimeDelta const &timeOut) // blocking
{
LOG_AS("Socket");

Expand Down Expand Up @@ -394,6 +403,18 @@ Socket::Socket(Address const &address, TimeDelta const &timeOut)
d->socket->state() == QAbstractSocket::ConnectedState);
}

void Socket::connect(Address const &address) // non-blocking
{
DENG2_ASSERT(d->socket);
DENG2_ASSERT(!d->socket->isOpen());
DENG2_ASSERT(d->socket->state() == QAbstractSocket::UnconnectedState);

LOG_AS("Socket");
LOG_MSG("Opening connection to %s.") << address.asText();

d->socket->connectToHost(address.host(), address.port());
}

Socket::Socket(QTcpSocket *existingSocket)
{
d = new Instance;
Expand Down Expand Up @@ -422,11 +443,11 @@ void Socket::initialize()
// Options.
d->socket->setSocketOption(QTcpSocket::LowDelayOption, 1); // prefer short buffering

connect(d->socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWereWritten(qint64)));
connect(d->socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
connect(d->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)), Qt::DirectConnection);
connect(d->socket, SIGNAL(readyRead()), this, SLOT(readIncomingBytes()));
connect(d->socket, SIGNAL(destroyed()), this, SLOT(socketDestroyed()));
QObject::connect(d->socket, SIGNAL(bytesWritten(qint64)), this, SLOT(bytesWereWritten(qint64)));
QObject::connect(d->socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
QObject::connect(d->socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)), Qt::DirectConnection);
QObject::connect(d->socket, SIGNAL(readyRead()), this, SLOT(readIncomingBytes()));
QObject::connect(d->socket, SIGNAL(destroyed()), this, SLOT(socketDestroyed()));
}

void Socket::close()
Expand Down

0 comments on commit a809df1

Please sign in to comment.