How to stop TIdTCPServer if clients are connected? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- shyub · 2022-02-25 11:14 dTCPServer1.Active:=false; - ERROR. AContext.Data.Free; AContext.Data := nil; AContext.Connection.Disconnect; - ERROR. IdTCPServer1.Contexts.UnlockList; - hangs up It is recommended to use an additional command passed to clients to disconnect them. But in my version, this is not suitable, because. clients are sensors. Is there any way to close the server without shutting down the clients? ---------------------------------------------------------------------- Remy Lebeau · 2022-02-25 17:12 Quote from: shyub on February 25, 2022, 12:14:39 pmdTCPServer1.Active:=false; - ERROR. Can you be more specific? What kind of error are you getting, exactly?  Can you provide a better example of what your server is actually doing? The most common problem encountered while deactivating TIdTCPServer is deadlocks caused by client threads trying to synchronize with the thread that is deactivating the server.  Is that what you are encountering? Quote from: shyub on February 25, 2022, 12:14:39 pmAContext.Data.Free; AContext.Data := nil; AContext.Connection.Disconnect; - ERROR. Again, you need to be more specific about the error. And, where exactly are you calling that code from?  The usual place to free the TIdContext.Data is in the TIdTCPServer.OnDisconnect event, but you should not be calling Disconnect() in that event.  If you are doing it anywhere else, you will have race conditions. Quote from: shyub on February 25, 2022, 12:14:39 pmIdTCPServer1.Contexts.UnlockList; - hangs up Are you also locking the Contexts list beforehand?  If not, then you have no business unlocking it like that. Quote from: shyub on February 25, 2022, 12:14:39 pmIt is recommended to use an additional command passed to clients to disconnect them. Any kind of unsolicited messaging from the server to the client is usually best handled in the TIdTCPServer.OnExecute event.  Typically, I suggest creating a per-client queue that the program can push messages into whenever desired, and then have the OnExecute event send the queued messages when it is safe to do so.  Any other way and you risk race conditions that can corrupt your communications if messages from multiple threads get overlapped on the wire. Though, in the case of a goodbye-type message, you could alternatively send that from the TIdTCPServer.OnDisconnect event instead, provided the client is still connected. Quote from: shyub on February 25, 2022, 12:14:39 pmBut in my version, this is not suitable, because. clients are sensors. And?  What does that have to do with anything? Quote from: shyub on February 25, 2022, 12:14:39 pmIs there any way to close the server without shutting down the clients? No, and that would not make sense to do that anyway. What are you REALLY trying to accomplish?  Are you maybe trying to make the server just stop accepting new clients, but still service existing clients?  THAT is doable, at least, via TIdTCPServer.StopListening().  But if you deactivate the whole server, it will need to disconnect any active clients. ---------------------------------------------------------------------- shyub · 2022-02-25 18:47 So far I have written two simple applications Server and Client for experimentation. In the future, a computer will be used as a server. Clients are GPRS modems connected to the level sensors, operating under the MOTBUS-RTU protocol (the modems connect to the server on their own). With a certain frequency, the server must poll the clients. However, if I need to shut down the computer, I need to stop the server. I can’t influence clients in any way (to disconnect a client, you need to turn off his modem, but there is no such possibility). ---------------------------------------------------------------------- Remy Lebeau · 2022-02-28 18:33 Quote from: shyub on February 25, 2022, 07:47:46 pmWith a certain frequency, the server must poll the clients. Easily accomplished using a simple loop in the TIdTCPServer.OnExecute event.  Just make sure you are not swallowing any Indy-based exceptions.  If you need to catch exceptions (error handling/reporting, cleanup, etc), just re-raise any exception that is derived from EIdException, let TIdTCPServer handle it internally. Quote from: shyub on February 25, 2022, 07:47:46 pmHowever, if I need to shut down the computer, I need to stop the server. Deactivating the server automatically disconnects all active clients and stops their worker threads.  When using TIdTCPServer correctly, that should not cause any problems. Can you please show your actual code that you are having trouble with? Quote from: shyub on February 25, 2022, 07:47:46 pmI can’t influence clients in any way (to disconnect a client, you need to turn off his modem, but there is no such possibility). Then what was the point of your earlier comment: "It is recommended to use an additional command passed to clients to disconnect them."