03-20-2023, 07:05 PM
(copied from my answer to your same question on StackOverflow):
Quote:By default, TClientSocket operates in non-blocking mode (TClientSocket::ClientType = ctNonBlocking). In that mode, the client uses an HWND window internally to handle socket events. It also means that the client connects to its server asynchronously, delivering a completion event to its HWND once the connection is successful or fails.
An HWND window has thread affinity, meaning it can only operate within the thread that creates it, and that thread must have a message loop to process and dispatch any messages that are sent to that window.
The TButton events are being fired in the main UI thread, and thus use the main UI message loop for processing. If the TClientSocket creates its HWND in the main UI thread, then everything is handled for you.
However, the TIdTCPServer events are fired in separate worker threads, one for each client that connects to it, and those threads do not have messages loops by default. So, you can't use TClientSocket in non-blocking mode inside of a TIdTCPServer thread without some extra work. Specifically, you must either:
- give each TIdTCPServer client thread a message-dispatching loop, ie in the server's OnExecute event.
- otherwise, put the TClientSocket into blocking mode (TClientSocket::ClientType = ctBlocking) instead, in which case no HWND is used at all, and the client connects to its server synchronously. However, you will then have to use a TWinSocketStream object to handle all reads/writes on that TClientSocket after its connection is successful.

