[Qt-interest] Subclassing QTcpSocket

BRM bm_witness at yahoo.com
Thu Apr 21 20:27:19 CEST 2011


----- Original Message ----

> From: Jason H <scorp1us at yahoo.com>
> I would like to make an observation, and invite comment.

I quite agree. I'd like to hear others comments on this approach as well, thus 
why I've been silent until now.
 
> It is not  immediately obvious, and what I've found is it is often better to to 
>
> not  subclass TCP socket to add application features, like client header. 

In my case it was just what made sense to do at least at first. Your suggestion 
certainly gives me pause to think how I might be able to do it a little better. 

 
> It is my observation that you should use a raw QTcpSocket which  directs bytes 
>to 
>
> your own class, which is connected() to the socket  instance.  Then this class 

> provides your application logic.  Immediately, you can then use QSslSocket with 
>
> your class. True, QSslSocket  inherits QTcpSpocket, but what do you have to 
>change 
>
> (source code) to use  QSslSocket? You'd have to make a QSslSocket derived class 
>
> with the same  functionality, and you then have code duplication. 

For my applications, I typically use all the same kinds of connections - all 
TCP. If at some point we want to move to SSL sockets, then I just switch it in 
one location - the primary class I derive from - and everything else 
automatically switches.

> Given that the  socket classes are QIODevices, wouldn't it be cooler if you 
>could 
>
> connect()  your application logic to any QIODevice? Say a file or compressed 
>byte 
>
> stream (QtIOCompressor) ? What I have found in my experience is that between  
>the 
>
> socket and your application, there can be many layers. For instance, in  HTTP, 
>a 
>
> worst case example would  be:
> ChunkedLengthDecoding->MimeDecoding->Base64Decoding->actual  data. If you had a 
>
> class to handle each stage, you can layer the byte stream  as needed
> socket.connectTo(&chunkedLengthDecoder)  ;
> chunkedLengthDecoder.connectTo(&mimePartDecoder);
> mimePartDecoder.connectTo(&base64Decoder);
> base64Decoder.connectTo(&applicationLogic);  // or 
> zipDecoder.connectTo(&applicationLogic)
> 
> where connectTo()  minimally connects the reading and writing signals and slots 
>
> (readyRead,  write(), etc) Not matter the translation scheme, your application 

> logic is  isolated from the communications.
> 

An interesting idea. In some respects it is nice in that it abstracts the core 
work from the sender/receiver methodology; however, it also means that something 
else needs to be setup to handle that.
By deriving directly from QTcpSocket (or QSslSocket) the normal API for all the 
connectivity is still used - I don't have to worry about it, provide it, etc. 
Nothing else needs to worry about setting up a QTcpSocket, QSslSocket, or 
anything else; it just uses the same interface on the derived object. If 
separating the two, something needs to worry about that part of the interface - 
not necessarily a bad thing, but something nonetheless. You also have to worry 
about instantiating the two - now you need something that instantiates the 
QTcpSocket/QSslSocket/etc as well as your derived class, versus just 
instantiating your derived class.

Again, these are not necessarily bad things in either approach, just slightly 
different and quite interesting.

Thoughts?

Ben




More information about the Qt-interest-old mailing list