Synapse TCP/IP client and server(Second Edition) lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- balazsszekely · 2023-03-30 12:26 I rewrote a large part of the client/server application from the following thread: https://forum.lazarus.freepascal.org/index.php/topic,48677.0.html Hopefully I managed to address all the issues mentioned there:   - dropped RecvPacket(@kupferstecher)   - thread safety(@kupferstecher and others)   - the server's thread list now is properly locked with critical sections, each thread waits until the list is unlocked, no more connections are dropped(@piola)   - server works as a daemon/service too(@datilas), tested only on windows   - proper variables initialization(@Phoenix) What's new:   - each file transfer has been moved to a worker thread, parallel file transfer is now possible   - newly connected/disconnected clients are highlighted for a custom amount of time   - added a new project(server_stress_test), server can be tested up to few thousand connections(requires 64 bit, see notes for more details)   - smaller stack size for each thread   - many more Notes:   - there is a limited amount of threads that a 32 bit process(2 GB address space) can create. For better performance please build synapse client/server with a 64 bit version of Laz/FPC   - developed with Lazarus_Trunk/FPC_3.2.0(64 bit) on the following OSs: Windows 10(64 bit) and Linux Mint Cinnamon 20.02(64 bit), with synapse trunk(rev. 267)   - ico and res files are removed(forum attachment size limitation), please re-add the icons   - I did not have enough time to thoroughly test the projects ---------------------------------------------------------------------- datilas · 2023-03-30 15:02 looking at the demo: synapse_daemon and synapse_client imagining a scenario where synapse_daemon is active and have 3 synapse_client connected on the server. I couldn't understand how I could send message from client1 to client2 or client 3 and I also could not understand how to send messages from any client to all clients I'm a beginner so I'm asking is there any demo in this situation? Sorry for my English I use google translator. ---------------------------------------------------------------------- balazsszekely · 2023-03-30 15:33 @datilas Quotelooking at the demo: synapse_daemon and synapse_client imagining a scenario where synapse_daemon is active and have 3 synapse_client connected on the server. I couldn't understand how I could send message from client1 to client2 or client 3 and I also could not understand how to send messages from any client to all clientsYou mean like in a chat application? This is not implemented currently, though it shouldn't be too difficult to implement. I mean the messaging part, audio/video streaming is done usually via udp hole punching, much more difficult to implement. QuoteI'm a beginner so I'm asking is there any demo in this situation?Unfortunately no. QuoteSorry for my English I use google translator.No problem, I understood everything. ---------------------------------------------------------------------- datilas · 2023-03-30 15:35 it would be great if no server exists a method like: GetClients so clients can see each other ---------------------------------------------------------------------- datilas · 2023-03-30 15:38 Quote from: GetMem on March 30, 2023, 05:33:23 pm@datilas You mean like in a chat application? This is not implemented currently, though it shouldn't be too difficult to implement. I mean the messaging part, audio/video streaming is done usually via udp hole punching, much more difficult to implement. yes. chat application. in my situation it would be just text. ---------------------------------------------------------------------- datilas · 2023-03-30 18:29 Let me explain my situation: I have an application that runs on multiple clients and multiple terminals per client. ex: client1 terminal1, terminal2, terminal3 ... client2 terminal1, terminal2, terminal3 ... I would like to upload synapse_daemon to a VPS and my application would connect with the synapse_daemon as soon as it runs and from my office I can send specific messages to each client or terminal or all terminals of a client. I could do this control using: Connection.FUser := client1_terminal1; in another terminal: Connection.FUser := client1_terminal2; ... but i would like to send a message from my office to anyone or everyone if there was a GetClients method on the server that returns all the necessary parameters to use the "SendMessage(AAC: TAcceptedClient; AMsg: String; AParams: TStringArray)" from the client I could filter from my application who would be the recipient. I do not know if i was clear. but do you have any idea how to do this? thank you very much. ---------------------------------------------------------------------- balazsszekely · 2023-03-30 19:16 @datilas I understood what are you after and as I mentioned in one of my previous post is not too difficult to implement it, however it does require time, which I don't have. I think your best shot is to convert a simple chat application coded in Indy. Just do a quick google search, I saw in the past chat demos on the net. ---------------------------------------------------------------------- Phoenix · 2023-04-01 07:57 Quote from: datilas on March 30, 2023, 05:38:36 pmyes. chat application. in my situation it would be just text. as a simple idea, on the server side when you edit the user list you can send an "update" message to all clients. Then the "chat-like" clients that need it, send the server a request for the list (the server will send via stream). Now that both have a synchronized list, you can use the parameter field to determine the client (for example for a private message) or without a recipient by sending back to all in broadcast from the server. However in any case the demo of @GetMem gives you all the tools to create what you want. Note: my English is also bad and I use google translate a lot so I hope you understand enough of the generic idea. @GetMem Thanks for this great improvement! There is also the stress test. ---------------------------------------------------------------------- Thaddy · 2023-04-01 09:06 Quote from: GetMem on March 30, 2023, 05:33:23 pmudp hole punching, much more difficult to implement. Well it is actually just a pair of sockets. It is a bit cumbersome, but it is not really difficult for you, although it IS difficult for beginners. I will add some code later, have to look it up. ((and translate it from fcl-web and fcl-net back to synapse) Note that hole punching is something that can be added to both and may be is a good idea to add an example. Will do my best. ---------------------------------------------------------------------- balazsszekely · 2023-04-02 07:34 @Thaddy QuoteWell it is actually just a pair of sockets. It is a bit cumbersome, but it is not really difficult for you, although it IS difficult for beginners.In order to cover all the NAT traversal mechanism you have to do a lot of work in my opinion. ---------------------------------------------------------------------- balazsszekely · 2023-04-02 07:41 @datilas I attach a chat like demo application where connected clients can communicate with each other(only messages, no file transfer or streaming). Start server or daemon, connect a few clients then click "Remote clients" as in the attached image. ---------------------------------------------------------------------- datilas · 2023-04-03 13:19 Thank you very much. it helped me a lot. it's exactly what i need. ---------------------------------------------------------------------- Warfley · 2023-04-03 13:46 Quote from: GetMem on March 30, 2023, 02:26:58 pm  - added a new project(server_stress_test), server can be tested up to few thousand connections(requires 64 bit, see notes for more details) On a side note for high throughput/heavy load servers it is unwise to scale with threads. By default Linux only allows around 65k processes, which includes all threads of all programms running. If you spawn up a thread for each incomming connection with thousands of connections per second, you are going to take a substantial chunk of the PID space. Also threads are quite expensive, so it's not just that PID limit, but also the resources available. Therefore what is usually done is to have one thread serve multiple (up to a few thousnad) connections, and serve them asynchronously through select/(e)poll (or WaitForMultipleObjects on Windows) together with non-blocking operations (as context changes for blocking operations are quite expensive). I'm not so familiar with synapse, I ususally use the "raw" berkley style sockets for raw TCP or UDP networking, so I don't know how good this is implementable with synapse, but might also be interesting to study for stress tests ---------------------------------------------------------------------- balazsszekely · 2023-04-03 17:31 @Warfley Synapse uses blocking sockets, with very limited support for non- blocking mode, so one thread per connection is required. This model has some advantages, the most important one it's easy to code because of the sequential processing. You already mentioned the cons: threads are expensive, there is a limited number of threads that can be created, etc...and yes I agree it's not scalable, but then not everybody needs high performance servers, capable of handling 100,000+ connections, it depends on use case. ---------------------------------------------------------------------- datilas · 2023-04-04 15:09 a TimeOut property on the client would be very good for networks with high latency on the server and low connection on the client so we could control the connection timeout. ---------------------------------------------------------------------- balazsszekely · 2023-04-04 15:18 Quote from: datilas on April 04, 2023, 05:09:14 pma TimeOut property on the client would be very good for networks with high latency on the server and low connection on the client so we could control the connection timeout. There is a ConnectionTimeout constant in unit uTCPSockets(default 5000 ms). Please increase it, then rebuild the client. ---------------------------------------------------------------------- ianr42 · 2024-02-11 03:04 I just wrote my own server - nowhere as good as this one - and have been having trouble with flushing sockets. So I thought I'd download this one and give it a go to cross check (and I agree with the older comments that it would be great to have this up in git somewhere!). It has a line in uTCPSockets (line 428) that says Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  FBlockSocket.ConnectionTimeout := ConnectionTimeout; The problem is that FBlockSocket - which is a TTCPBlockSocket - has no member called ConnectionTimeout  - either directly or inherited. Well, not in my current synapse version, or on http://synapse.ararat.cz/doc/help/blcksock.TTCPBlockSocket.html I can, of course, comment out the line - but I'd be curious to know what version of synapse had that as a variable, or has the synapse library been edited for this project? ---------------------------------------------------------------------- rca · 2025-07-09 18:58 I'm sending a simple test file, "test.txt", from the server to the client. The first time it sends without any problems, but when I try to send it again, the following error message appears on the server: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Error sending message "READY" : Other Winsock error (32)(32) And on the client side: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Connection reset by peer(104). I'm using the fixes branch of Lazarus 4 and fixes FPC 3.2. Ubuntu 24.04 64-bit. How can I fix this? ---------------------------------------------------------------------- Thaddy · 2025-07-09 19:04 By not using Synapse but the code from fpc-web/net? Btw, that is not absolutely necessary, but it is necessary that your security protocols are up-to-date. ---------------------------------------------------------------------- Warfley · 2025-07-09 20:37 Quote from: rca on July 09, 2025, 08:58:50 pmHow can I fix this? Well with this great amount of information you gave us on the code you run... Either your server crashed or you closed the socket without a proper shutdown. Either way, your server killed the connection. ---------------------------------------------------------------------- rca · 2025-07-09 20:46 Quote from: Warfley on July 09, 2025, 10:37:31 pmQuote from: rca on July 09, 2025, 08:58:50 pmHow can I fix this? Well with this great amount of information you gave us on the code you run... Either your server crashed or you closed the socket without a proper shutdown. Either way, your server killed the connection. I downloaded the .zip file from the first post. There is a server and a client, with the option to send messages or files. I haven't modified the original code. The error occurs after successfully sending a file from the server to the client once. After that, you can no longer successfully send files.