December 22, 2011

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

How to wait on read and close event simultaneously on QTcpSocket

Page  
1

Hi,

I wrote one thread based application, where inside the run() of thread I am waiting for readyread using WaitForReadyRead(-1), infinitely. But it crashes here when socket has been closed at the server.
How can we wait for read and close event at once so that I can return from run() function safely in case of socket closure.

Regards
Ashish

16 replies

December 22, 2011

koahnig koahnig
Mad Scientist
2193 posts

You could wait for a definite time interval in a while loop with the condition that the connection is still established through check of state [developer.qt.nokia.com] .

December 22, 2011

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

I tried to wait for 1 second and then whenever be timeout occur I am checking the socket state, but neverthless it crashes in waitforreadyread again.

I am looking for something similar to WSAEventSelect function whereas we can put socket into FD_READ and FD_CLOSE events and can use waitforobjects for these event handles.

Regards
Ashish

December 22, 2011

koahnig koahnig
Mad Scientist
2193 posts

IMHO it is not a good design to open the socket and just wait until something will be sent. Typically you establish a connection and connect the readyRead signal [developer.qt.nokia.com] signal with a slot handling the reading of the information. You have then the possibility to check the number of bytes received.
When the connection to the dies, then the socket is dead and you might want to remove it or reestablish the connection.
Did you have a look to the fortune example code [developer.qt.nokia.com]

December 23, 2011

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

Yes I have gone through that code(blocking and nonblocking fortune) and implemented that signal and slotting mechanism as well. But it brings slowness in my application when sockets are more(e.g. 5), and we are getting data from the server on all these sockets.

Thats the reason I created one thread per socket to server the requests, but got strucked at this point.

Anyways thanks a lot for your suggestions….
These discussion are really making my life easily.

Regards
Ashish

December 23, 2011

koahnig koahnig
Mad Scientist
2193 posts

I would assume that you just have to put the whole signal-slot mimick for one socket into one thread. That is probably the easiest path to move forward.

December 23, 2011

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

Ok!!! Sounds a nice approach, let me give a try to this and then I will come back.

January 12, 2012

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

Hi,

I would like to disscuss about the design approach suggested by you earlier , mimic the func of sockets in a separate thread for faster comm.

Here is the design what I thought:

  1. I am creating the socket in a class connecting it to server, from that class I am launching separate therad of execution.
  2. Inside run method of that thread , I will merely connect the signals(readyRead, Disconnect, error)
    and call exec(). All signals will be associated with the slots defined in the thread class only.
  3. Based on some data arrival from server in these slots I will be calling thread owner class to do some stuff on QWebView.

Please suggest is this a proper approach to go with async socket comm.

January 13, 2012

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

In addition to add in the above discussion I am getting below mention messages in DbgViewer.

[2684] QSocketNotifier: socket notifiers cannot be disabled from another thread

[4040] QSocketNotifier: Multiple socket notifiers for same socket 960 and type Read

January 13, 2012

Andre Andre
Area 51 Engineer
6075 posts

Your issue is probably, that the sockets are not created in the socket thread, but in the main thread. And be very careful with triggering UI changes from a thread. You can use queued signal-slot connections only for that.

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

January 13, 2012

koahnig koahnig
Mad Scientist
2193 posts

Ashish Mittal wrote:
In addition to add in the above discussion I am getting below mention messages in DbgViewer.

[2684] QSocketNotifier: socket notifiers cannot be disabled from another thread

[4040] QSocketNotifier: Multiple socket notifiers for same socket 960 and type Read

I can only interpret the error messages you see.
Presumably you are using a Socket several times and assign it to different threads. This may happen when using:

  1.  
  2. for ( int i = 0; i < n; ++i )
  3. {
  4.     assignSocket ( &sckt );
  5. }

Better would be:

  1. for ( int i = 0; i < n; ++i )
  2. {
  3.     QTcpSocket *sckt = new QTcpSocket;
  4.  
  5.     assignSocket ( sckt );
  6. }

When assignSocket is the method you are using to assign sockets to different threads you are using the same socket for all threads. In the second case you will have independent sockets.

Note: just example code not tested

January 13, 2012

bu7ch3r bu7ch3r
Lab Rat
56 posts

Just use a mutex an lock it before an unlock it when both request are finished.

 Signature 

for(int i = 200; i > 0;)
try
{
//do something
}
catch(...)
{
i—;//try again
}

January 13, 2012

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

Hi,

I am not getting “QSocketNotifier:bla bla…” messages if I use Async approach.
I am totally confused at this movement , what should be the correct desing for this kind of application in Qt.

Please suggest :-
Can I derive a class from QThread, and inside that class
I will create a socket and QWebView, and then I will connect slots for network comm inside run method and then based on slots call , I will manipulate the webview.

Please suggest the appropriate design.

January 13, 2012

KA51O KA51O
Robot Herder
397 posts

You can only manipulate GUI elements inside the main thread. What you could do is get the content from the WebView (e.g. via getHtmlText() or something) pass the resulting string to your worker object which resides in another thread manipulate the string there and pass it back to the main thread and then finally update your WebView.

also read this article [labs.qt.nokia.com], you should not subclass QThread. You can do it but its not the intended use anymore.

February 11, 2012

Ashish Mittal Ashish Mittal
Ant Farmer
151 posts

Hi,

Is there no way in Qt to get the data from the QTCPSocket without calling waitForReadyRead() function.

I tried to call the function readData() , but it always returns 0, if I am calling waitForReadyRead() then calls readData() , then it succeeds.

Actually prob is if I am in waitForReadyRead() then it socket closure happpens at server then this is giving me crash.

One more question is , I have created my sockets in worker thread , and register readyRead signal with some slot in that thread only.

I have two diff socket at client created in two diff thread.
When I print threadID in data ready read slot, I am getting same thread id, I am confused it should be different thread id.

Please correct my understanding.

February 11, 2012

Andre Andre
Area 51 Engineer
6075 posts

Yes, of course there is. You should connect to the readyRead() signal, and only when you get this signal call readData().

 Signature 

Looking for Qt developers to join our team @ i-Optics: https://qt-project.org/forums/viewthread/25393/

Page  
1

  ‹‹ How to run "Network chat client example" in QT demos ?      [Solved]How to create Executable for windows based environment? ››

You must log in to post a reply. Not a member yet? Register here!