[Interest] [Qt 4.8] Subclassing QAbstractSocket (for ICMP)

Jason Cipriani jason.cipriani at gmail.com
Mon Jan 28 04:02:01 CET 2013


I am writing an application that has to send and receive ICMP messages.
Primary goal is to minimize amount of platform-specific code. To that end I
am trying to extend QAbstractSocket to provide an ICMP socket
implementation. However, I'm stuck on the fundamentals working with
QAbstractSocket. My development environment is Windows.

First attempt was to create a socket [socket(AF_INET, SOCK_RAW,
IPPROTO_ICMP)], instantiate a QAbstractSocket, and call setSocketDescriptor
-- no subclass. There were issues:

  1) I needed to call WSAStartup/WSACleanup. I feel that Qt is already
doing this somewhere and I'd like to use Qt's platform-independent
initialization instead.
  2) QAbstractSocket doesn't really provide a public way to send data to a
specific host (ICMP is connectionless).
  3) I tried setSocketDescriptor + UnconnectedState then a call to
connectToHost anyways, but the call was unsuccessful.

I gave up on this approach and decided to subclass QAbstractSocket instead.
I do not have the Qt source locally, I am referring to it online. My
primary sources of information are the QAbstractSocket documentation, and
the QTcpSocket/QUdpSocket source code (looking at those as examples).

However, I quickly realized that I'm not really sure what I'm doing here. I
haven't spent *too* much time investigating, I decided to ask here for the
best initial approach instead. All I have is a constructor and I'm already
stuck:

ICMPSocket::ICMPSocket (QObject *parent) :
    QAbstractSocket(QAbstractSocket::UnknownSocketType, parent)
{

#ifdef Q_WS_WIN
    SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
    if (s == INVALID_SOCKET)
        qDebug("socket() failed");
    else
        setSocketDescriptor(s);
#endif

}


I have a lot of questions here:

  1) Is creating a socket and calling setSocketDescriptor in the
constructor the right approach? Will QAbstractSocket then manage the
descriptor from here on out?
  2) QUdpSocket/QTcpSocket use an underlying socket engine for many things
(e.g. platform-independent error codes to strings, initialization, etc.). I
don't know how to access the socket engine. QUdpSocket/QTcpSocket have a
private object, but in order to use QAbstractSocketPrivate, I have to have
qabstractsocket_p.h installed locally. It *seems* like I should be able to
do this without the Qt source installed, but I may be wrong. How can I
access the features of the underlying socket engine? Do I have to build
against the Qt source?
  3) On Windows, can I accomplish this without calling WSAStartup()
explicitly? Is there a platform-independent method of initializing the
network subsystem? The above code fails as-is because WSAStartup has not
been called (I had hoped QAbstractSocket's constructor to indirectly lead
to network initialization but it does not).

Any guidelines, some pointers to relevant documentation (or maybe I missed
some things in the Qt documentation), or advice would be helpful. I seem to
be stuck on some initial hurdles.

Thanks!
Jason
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130127/d91df5f9/attachment.html>


More information about the Interest mailing list