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

Thiago Macieira thiago.macieira at intel.com
Mon Jan 28 07:58:17 CET 2013


On domingo, 27 de janeiro de 2013 22.02.01, Jason Cipriani wrote:
> I am writing an application that has to send and receive ICMP messages.

That means you're running as root and you're using raw sockets. Please 
continue using raw sockets, not QAbstractSocket.

QAbsractSocket::setSocketDescriptor requires a socket of type SOCK_STREAM or 
SOCK_DGRAM. If you pass anything else (like ICMP raw sockets), funny things 
will happen.

My suggestion: abandon your approach and create your class that is independent 
of QAbstractSocket.

>   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.

That's done automatically when the QNativeSocketEngine is created. If you 
create your socket before calling setSocketDescriptor (which you usually do), 
you need to call it yourself. You can also just create a dummy socket and try 
to connect somewhere, or create a UDP socket and just bind it.

>   2) QAbstractSocket doesn't really provide a public way to send data to a
> specific host (ICMP is connectionless).

Correct. As I said, it's not meant to do ICMP. You need to add your own 
methods, preferably to your own class.

>   3) I tried setSocketDescriptor + UnconnectedState then a call to
> connectToHost anyways, but the call was unsuccessful.

connectToHost makes no sense for ICMP. Besides, there's a long-standing bug in 
setSocketDescriptor in unconnected state + connectToHost. If you do that, 
it'll close your socket and create a new one.

>   1) Is creating a socket and calling setSocketDescriptor in the
> constructor the right approach? Will QAbstractSocket then manage the
> descriptor from here on out?

No and no.

>   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?

You can only do it from inside QtNetwork. The classes are not exported.

You must modify the sources and add the feature inside QtNetwork itself. Then 
rebuild Qt.

>   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).

There's QWindowsSockInit. If you're modifying QtNetwork, you have access to 
it. If you're not modifying it, then you can't access it and there's nothing 
cross-platform.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 190 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130127/7c907f16/attachment.sig>


More information about the Interest mailing list