PeaShooter_OMO 11 Posted February 14 (edited) Good day I have a server service which I originally created using Indy. I am now stuck with an issue which I am struggling to resolve. We have a deadline and that server service needs to be rolled out so I decided that while my Indy issue is being looked at I will see what alternatives are available and how they perform. The server I developed can sometimes accept hundreds of connections in a minute and files are exchanged between the server and the clients. There also exist occasions where another of the same server type will connect to this one and hundreds or even sometimes thousands of files maybe interchanged between them in a single session. I believe threads are crucial in such a situation and I was wondering how ICS will be able to perform in this sutation and aspecially with threads. I have read posts and comments about the differences between Indy and ICS. For example in this one long ago, ICS: Thread or not and in this one, ICS or Indy for a new project Francois notes that the developer has the freedom to use threads with ICS if he pleases and from what I have seen ICS has made provisions for the use of threads. But this post Stable Communication between ICS TSslWSocket and TSslWSocketServer and aspecially this comment from Angus (Comment) made me wonder whether threads are even a good idea with ICS. I will agree that that post's original developer's situtaion might not be known well enough to be able to make the assumption that threads are not a good way to work with ICS so I will rather ask and find out. Assuming threading is done correctly and also apart from the usual comment of "Most of the time you don't need threads in ICS, look how nicely my stuff works without it" and of course Angus' comment I would like to ask; Honestly now, can ICS work as expected within a multi-threaded environment closely built around ICS's framework? Second question... Can you use the Send method of ICS's Socket component from outside the original thread that the component was attached to without it bombing out somewhere down the line. In other words is it thread-safe to do so? Thank you for your input. Edited February 14 by PeaShooter_OMO Share this post Link to post
Angus Robertson 574 Posted February 14 Can not recall what I said in my previous posts here, but can only reiterate that for serving files, threads are not necessary, there is minimal blocking activity. There is a limit to how many new SSL/TLS connections can be accepted each second due to the processing, but once the connection is open, hundreds of connections can run in a single thread. Threads are necessary to make use of more than one CPU. ICS does have a threaded server component, but it does not support SSL/TLS or the web server and has not been tested for 10 years. If you use threads in ICS, each thread has its own message queue and handler, so you can not send from a different thread. Angus Share this post Link to post
Remy Lebeau 1397 Posted February 14 6 hours ago, PeaShooter_OMO said: I have a server service which I originally created using Indy. I am now stuck with an issue which I am struggling to resolve. We have a deadline and that server service needs to be rolled out so I decided that while my Indy issue is being looked at I will see what alternatives are available and how they perform. Which issue is that? Share this post Link to post
FPiette 383 Posted February 14 If you want to use ICS in threads, a good design would be to have all socket activity executed by the thread itself. If the data to be sent comes from another thread or received data must be processed by another thread, don't share the ICS component but use standard inter-thread communication techniques to do the transfert. Note that processing by ICS is not a CPU intensive process so you won't gain much using thread. Instead it is better to keep actual data processing along with the ICS component in the thread. For example, you can use a thread in a server application to handle a single client (or a few hundreds). Use ThreadAttach and ThreadDetach to move socket handling from one thread to another thread. Writing a multi-threaded application is hugely more complex than a single-threaded application, debugging is particularly difficult. You benefit from thread when computing can be done in parallel. For file transfer operation, there is almost no processing involved so benefit is low. Don't forget that the real network throughput is frequently the limiting factor. And even if you have a fast hardware speed (1Gbps for example) doesn't means that the network card you have is able to sustain such throughput. Share this post Link to post
PeaShooter_OMO 11 Posted February 14 (edited) 1 hour ago, Remy Lebeau said: Which issue is that? It is the post on the Indy Gitter Chat Room which you are currently looking at. I am researching other libraries while that one simmers in the background. My time might just run out and I need to be prepared. The post on Gitter Edited February 14 by PeaShooter_OMO Share this post Link to post
Remy Lebeau 1397 Posted February 14 33 minutes ago, PeaShooter_OMO said: It is the post on the Indy Gitter Chat Room which you are currently looking at. Oh. I didn't realize that was you. Share this post Link to post
PeaShooter_OMO 11 Posted February 14 (edited) 1 hour ago, FPiette said: Writing a multi-threaded application is hugely more complex than a single-threaded application, debugging is particularly difficult Indeed 1 hour ago, FPiette said: You benefit from thread when computing can be done in parallel. For file transfer operation, there is almost no processing involved so benefit is low I understand that even though connections are separated by means of sockets one would still be able to look at the incoming data across them as sort of "sequential" in nature and I assume in general one would be able to process that data similarly but these servers don't just do that the whole day. They also look at other processes which also include FTP and disk access along with DB access and then need to create new data and send it between them whenever required. The whole cycle is a bit time critical and in the very least I would expect the listening Server side to be in its own thread and perhaps hand off some major work to another thread, even socket access. Obviously Indy's server side does the thread per connection automatically and I might well be overthinking this when looking at ICS but the question I asked above about Sending from another thread was the very first thing I was thinking about. You see, I created a re-usable TCP framework which is used in different projects at our company including the above Server service and I want to adopt an approach that can be used in general by most if not all those projects. I also need my applications to be able to send network data to the other side at any point and from any thread. If ICS does not work well with that any thread sending then sure, I could transfer the data to be sent to the thread owning the socket. No problem. Now that I think of it, I wonder if that is not perhaps the reason for my issue with the current Indy implementation.... maybe Indy also does not like that I do that. Maybe @Remy Lebeau would be able to provide some insight regarding that. My research is to find solutions which I might have to consider in future. Edited February 14 by PeaShooter_OMO Share this post Link to post
Remy Lebeau 1397 Posted February 14 (edited) 27 minutes ago, PeaShooter_OMO said: I also need my applications to be able to send network data to the other side at any point and from any thread ... Now that I think of it, I wonder if that is not perhaps the reason for my issue with the current Indy implementation.... maybe Indy also does not like that I do that. Indy allows that just fine - provided you adequately serialize access to the socket to avoid multiple threads overlapping their outgoing packets. Although multiple threads CAN send to the same socket provided they don't overlap, it is generally a better idea to handle all of the sends in a single thread instead. Edited February 14 by Remy Lebeau 1 Share this post Link to post
FPiette 383 Posted February 15 12 hours ago, PeaShooter_OMO said: my issue with the current Indy implementation This forum is not the place to discuss any issue with Indy, nor any comparison between ICS and any other socket component. If you want to discuss about other socket components go to their support channel. You are welcome to discuss about ICS here and nothing else. Share this post Link to post
FPiette 383 Posted February 15 12 hours ago, PeaShooter_OMO said: I would expect the listening Server side to be in its own thread and perhaps hand off some major work to another thread, even socket access. A good architecture, scalable architecture, is to have ONE thread for the server component for a given protocol. That thread will handle all client communications (that's OK for up to one thousand clients) and unload any processing to worker threads. You can also consider splitting the application between different processes which will handle a single protocol and possibly use IPC to make those processes talk to each other if required. Having a single process doing everything is the best way to have an unstable system almost impossible to debug. 1 Share this post Link to post
Kas Ob. 121 Posted February 15 14 hours ago, PeaShooter_OMO said: I understand that even though connections are separated by means of sockets one would still be able to look at the incoming data across them as sort of "sequential" in nature and I assume in general one would be able to process that data similarly but these servers don't just do that the whole day. You lost me there, i don't understand the context of this assumption the why and for what, also sockets are sequential when they are TCP (and only) . About the mentioned error in the called Gitter (first time i see it), it is clear and without doubt that your receiver (client or server you didn't mention or i just miss it) had received unprocessed data by SSL/TLS handler, the other party sent plain data instead of the layered or secured TLS buffer. With this in mind then your server/client had messed up the integrity of the data (or stream), this easily can be happen if you are using multithreaded design and mixing protocol or multithreaded with corrupted (not protected or thread safe) socket list, example a buffer of plain data should first processed for layered security, then that buffer should be sent to the one and only socket established the secure connection or establishing one, here no matter if you switch between ICS or Indy the problem will persist, because your socket handling by your threading model is broken or faulty ! So as suggested above, provide the smallest but detailed (preferably code) how you handle threads and sockets and how are you separating them. Also expanding on this will help, Quote 3. The "file-sending" peer will not do anything with the ACK upon receiving it but will still take it from its TCP buffer. Your own implemented data ACK or the the default TCP ACK ? Also as Francois mentioned to not complicate this thread with ICS and Indy, you might need to start another thread. Share this post Link to post
PeaShooter_OMO 11 Posted February 16 @Kas Ob. If you look at the replies of that Gitter post you will see that the issue is actually not SSL/TLS. I did submit a demo app and code to that Gitter post which demonstrates the issue. Share this post Link to post
Kas Ob. 121 Posted February 16 1 hour ago, PeaShooter_OMO said: the issue is actually not SSL/TLS. I didn't say it is SSL/TLS issue, i used that error (issue) to make some logic (deduce) about failed synchronization or wrongly sent buffers due faulty destination assignments between threads and sockets. Share this post Link to post
qubits 20 Posted February 20 Cherish both ICS and Indy.. And you could use either to accomplish something.. Something to look over.. A server app with user configurable gui.. Each element represents a connected clients feature/function.. Clients are ESP32 MCU's, with quite a bit of functionality.. App allows you to control connected clients.. Connected clients can also inter-communicate through the server.. As I'm not expecting thousand of connections, I'm using a DB server backend.. Used Indy for the server here.. Not gonna sugar coat it, it's complicated.. Works good, was driving my bot around with it, ported it to RaspPi.. fun stuff, good luck.. ~q Share this post Link to post
FPiette 383 Posted February 20 (edited) This post can be deleted. Edited February 20 by FPiette Share this post Link to post
PeaShooter_OMO 11 Posted February 20 (edited) 58 minutes ago, FPiette said: To be deleted. What should be deleted? Your reply? Edited February 20 by PeaShooter_OMO Share this post Link to post