C++ Embarcadero TTcpServer and TTcpClient - c++

I want to know how to work with connected clients on TTcpServer class?
I got a client connected on method "ServerAccept" whats next? How can i work with them?
I need to start from ServerAccept a new thread to work with socket client?

The TTcpServer.OnAccept event is triggered when the TTcpServer.Accept() method is called and a client is accepted. ALL socket work with that client has to be done within the context of the TTcpServer.OnAccept event, using the methods of the TCustomIpClient object that is provided by the event. As soon as the event handler exits, TTcpServer closes the connection. If the TTcpServer.BlockMode property is set to bmThreadBlocking, the OnAccept event handler runs in a thread managed by TTcpServer so you do not need to create your own thread. Otherwise, you need to call the TTcpServer.Accept() method in your own code, in which case you can call it in your own thread if desired.

Related

How can I prevent transmission of execution control to the last executed function when a Qt signal is emitted?

I have a Qt C++ program. I have a main driver MainWindow and a TCPClient class. The TCPClient class is used to communicate with a remote server, transmit some data over TCP, request for processing of the data and receive processed data from server. In my TCPClient class, I am using QAbstractSocket signal disconnected. This is emitted when the connection with the server is disconnected. In the function (slot) which handles this disconnect signal (ifDisconnected), onCompletionCallback function of the MainWindow is called. Now my question is how do I prevent the transmission of execution back to TCPClient after the said onCompletionCallback finishes executing. What's following is incomplete code describing the issue;
mainwindow.cpp
void MainWindow::on_connectButton_clicked()
{
std::function<void(void)> callback std::bind(&MainWindow::onCompletetionCallback, this);
tcpClient_ = new TCPClient(callback)->connectToServer(someData);
}
void MainWindow::onCompletetionCallback()
{
if(tcpClient_->isRequestSuccess())
{
QJsonDocument responseJson = tcpClient_->getResponse();
return; //When this finishes executing, I want to prevent the execution control to go back to TCPClient
}
}
TCPClient.cpp
void TCPClient::connectToServer(QJsonDocument requestJson)
{
// Removed code of other connect signals
connect(tcpSocket_, &QTcpSocket::disconnected, this, &TCPClient::ifDisconnected);
}
void TCPClient::ifDisconnected()
{
// Here the callback is called. After the callback finishes executing, I don't want execution to return to `TCPClient`.
onCompletionCallback_();
return;
}
How do I solve this problem. I need to use the signal disconnected because QAbstractSocket doesn't provide any utility function to check if the connection is available.
You cannot and you should not prevent that the signal handler returns to caller. Otherwise, you would corrupt your call stack.
The actual question (for me) is: What is the caller of signal handler?
To understand what I mean, please, read the Qt doc. about QObject::connect() with special attention to Qt::ConnectionType.
The default is Qt::AutoConnection which means:
If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
Qt::DirectConnection:
The slot is invoked immediately when the signal is emitted. The slot is executed in the signalling thread.
The most common case (for me) are signal handlers called for modifications of GUI objects (i.e. widgets, etc.) which modify data or other widgets in response (in strict single-threading manner). In this case, it is Qt::DirectConnection i.e. the widget signal emitter is the caller of my signal handler.
A possible error (I did once) is to delete the widget which emitted the signal (e.g. handling a close button event of a dialog) – bad idea: I destroyed the widget with a pending method call on call stack. After returning from my signal handler it ended in a crash. The caller method (the signal emitter) had no instance anymore, or in other words: its this was invalidated. (It's like sawing the limb you sit on.) (Btw. deleteLater could be one solution for this. I found SO: How delete and deleteLater works with regards to signals and slots in Qt? concerning this.)
Considering your code sample
connect(tcpSocket_, &QTcpSocket::disconnected, this, &TCPClient::ifDisconnected);
I suspect this is a Qt::DirectConnection.
The other aspect: calling a main window function out of the TCP client thread is something which needs special attention as well. The caller is something in the TCP client thread but addresses an object (the main window) which resides in the (different) GUI thread. Phew. Everything (exept local variables) what is accessed in this called function must be mutex guarded if the GUI thread itself uses this as well.
So, what about the other options:
Qt::QueuedConnection:
The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread.
For communication between threads, IMHO, the Qt::QueuedConnection is the safer way: The TCP client emits a signal which results in a respective entry in the event loop of the GUI thread (assuming the main window was given as receiver object). The GUI thread will pick up this entry while processing its event loop. In this case, the event loop of GUI thread is the caller of the signal handler. The TCP client thread didn't wait after sending the signal request but continued its processing. If this is not desired the third option comes into play:
Qt::BlockingQueuedConnection:
Same as Qt::QueuedConnection, except that the signalling thread blocks until the slot returns. This connection must not be used if the receiver lives in the signalling thread, or else the application will deadlock.
The Qt::BlockingQueuedConnection lets the signal emitter (the TCP client) until the GUI thread has processed the signal handler. (The warning about the dead-lock is not effective here as the TCP client thread is the signaling thread where the GUI thread is the receiver.)
I'm a little bit uncertain what to recommend. I'm afraid your application needs a little bit re-design but for this the code sample is a little bit to incomplete.
A possible solution:
Introduce a Qt signal emitted when completion is required. The MainWindow::onCompletetionCallback() may be connected as signal handler to this TCP client signal using a Qt::BlockingQueuedConnection.
If the end of transmission is recognized it may perhaps destroy the TCP client thread. However, a thread which kills another thread is no good idea in general (and I'm not sure how Qt handles this "under the hood"). Therefore, a better concept would be: If the end of transmission is recognized the main thread flags the TCP client thread to leave it's main loop. Flagging could be done e.g. with a std::atomic<bool> (or you stay in Qt which has its own pendant QAtomicInt. The TCP client checks this flag in its main loop or at least after emitting a signal and exits in case.
A last hint:
If you are uncertain whether you understood the all the signal stuff correctly – I checked my understanding by putting a break point into the signal handler and inspecting the call stack when execution stopped at that break point. This is easy and straight forward (except you are dealing with mouse or drag & drop events).

Socket select() blocks other UI threads

In my MFC application , I am using TCP/IP socket for communcating and getting data from a server.During this process I am displaying a modelless dialog with static text and progress control.During communication I am updating the static text and progress control in a separate user thread(AfxBeginThread).
If I try to communicate to wrong ip the sockets select function with timeout value 5 secs blocking the displaying of dialog with static text and progress control(I.e the dialog hangs, the controls are getting displayed).
Once the socket comes out from select function the dialog is getting displayed properly.
How to fix this problem?
In MFC, I'd strongly recommend using CAsyncSockets, and just reacting when data comes in from the server. You probably have no need to spin up a thread at all.
If you were going to spin up a separate thread for part of the job, you'd want to allocate tasks to threads somewhat differently. You always want to leave UI updates in the main thread (the one that was created by default). If you were going to use (for example) a blocking socket, and call select on it, you'd want to move that work to a separate thread, and leave the UI updates in the thread that was created by default. Then the thread handling the socket could (for example) send messages to the UI thread to tell it about what's going on, so it could update the UI appropriately. But, as already noted, you probably just want to use a CAsyncSocket, in which case you won't need a second thread at all.

Qt : qt cannot send events to objects owned by a different thread - Why

I am developing an application with Qt whereby I want to update my GUI from another unrelated class with functions executing in a different thread.
I registered a callback function from the Qt GUI class to the other class using standard C++ constructs std::function and std::bind.
On trying to execute the GUI callback function from the other class, my program crashes with "qt cannot send events to objects owned by a different thread".
My questions are, what is happening here exactly. Why is it not permissive to communicate between two threads like this. Is it possible to resolve this in some way , or does Qt just not allow other unrelated functions to update the GUI in this way ?
For information , I am using portaudio libraries on windows. It executes a callback in a different thread. When I receive audio, I try to update my GUI.
Thank you in advance
You're probably being thrown off by the "send events" phrase. In Qt, this phrase has a strict technical meaning. Namely:
to send events means to use QCoreApplication::sendEvent, which then immediately invokes QObject::event on the receiver. It is an error to send events when the sending and receiving threads are different.
to post events means to use QCoreApplication::postEvent, which posts the event to the receiving object thread's event queue. The QObject::event on the receiver is invoked later by the receiver thread's event loop.
When objects live in different threads, you're not allowed to send events, only to post them. This points to the underlying cause of your issue/
Any method you access on a QWidget or a derived class must be accessed on its thread(), i.e. the main thread. Everything inside of QWidget can use sendEvent freely as the sending thread and receiving object's thread are identical by contract. By calling QWidget methods from the wrong thread, you break that contract by indirectly using sendEvent and thus fail.
Only methods that you yourself have implemented and are thread-safe can be called from other threads - and they can't use sendEvent.

Callback with XPCOM

I would like to implement the observer pattern similar to Timer component. Instead of calling a callback by time expiration, the callbacks that are observers of a topic would be called from system events (like new file created, or a new e-mail received, etc.). I tried using nsIObserverService in the component XPCOM, but it seems that functions from component aren't able to call observers in JavaScript by using NotifyObservers. The NotifyObservers only works when is called from JavaScript.
Thanks in advance
Example::Example always runs on the main thread (because it's being created by your script). So it never creates a proxy to the observer service. But the call to Example::Call from Ex::Run happens on the background thread, and I think in this case the call to NotifyObservers returns NS_ERROR_UNEXPECTED (which you ignore).

Why is my DCOM client locking on a call to SendMessage?

Running on XP. I have a client that calls calls CoInitializeEx(NULL, COINIT_MULTITHREADED), loads a (local) DCOM object, and attaches an event interface so the DCOM object can send back events. The client looks a lot like notepad with a multi-line textbox covering the client area to display event messages. Here are the calls that create a lock-up:
Client calls p->DoStuff() on the DCOM object.
The DCOM object calls c->DoStuffEvent() on the client while processing DoStuff().
The client sends a EM_REPLACESEL message to the child textbox to have it display "stuff is happening"
The client freezes on the SendMessage(EM_REPLACESEL). The client's call to p->DoStuff() is done on a the main thread while the SendMessage(EM_REPLACESEL) is done on a different thread. I'm sure this has something to do with the problem.
Can someone explain what's causing the lock and how I might work around it? The client and DCOM objects are coded by me in MSVC/ATL, so I can modify them both as needed.
It would appear that the window was created by the main thread. So that is the only thread that can call the window proc. When you SendMessage from the other thread, what it actually does it to put the message into the main thread's queue and then wait for the main thread to call GetMessage or PeekMessage. Inside the call to GetMessage or PeekMessage, Windows notices a waiting cross-thread SendMessage and passes that message to the window proc, then it wakes the second thread and lets it continue.
If you don't care about the return value of SendMessage(EM_REPLACESEL), you can use SendNotifyMessage instead. But if you do this, you need to make sure that the string you pass with the EM_REPLACESEL message is still valid when the message is finally delivered.
As per the SendMessage documentation, SendMessage does not return until the function is completed. It is synchronous. I believe it is always answered on the UI thread as well. If you want to do an asynchronous message pass, then you should use PostMessage.