I wanna build a TCP/IP server that will be used by up to 100 concurrent clients, but still not sure how to get started.
at least I need the server to this:
And another Delphi library option would be synapse which provides a simple framework that can easily be extended. There is an IOCPPool demo available in the contributed files which may be of assistance.
Synapse is more of a framework of classes than a component library. There is a vibrant and active user community that is ready to support any challenges. I use this library in Delphi 2010 without any problems (although I use the latest development version from SVN).
Being as they are not components, it is very easy to use the classes in simple console applications or windows services.
On a Windows platform you are probably best to avoid select
for large numbers of concurrent connections (100 isn't a large number of connections though). However, avirtuos is correct in that you want to avoid any 'thread per connection' models. The most efficient approach on Windows is to use overlapped I/O and I/O Completion Ports. This allows you to manage 10s of thousands of connections with a small number of threads (2 or 3, perhaps).
I don't have any Delphi experience so I've no idea how easy it is to interact with C++ code BUT I have a free C++ I/O Completion Port server framework (available from here) that would, at least, show you how the standard Win32 I/O Completion Port API operates. It might be useful to you and you might be able to do something similar in Delphi.
Some excellent component sets that are useful for situations like yours (and much more) are kbmMW and RemObjects. There are some other good sets, too, I think, you could do a search of archive or ask a question in Embarcaderos' Delphi thirdpartytools newsgroup. You can search archives here: http://codenewsfast.com/
I've recently run into this problem. Here is a link to a C++ example using EPOLL to manage hundreds of multicast sockets. Yours would be TCP/IP but that's really just a simple change.
Which ever method you choose, for 100+ simultaneous sockets/clients you will want to use a thread model that relies on poll, select, or preferable epoll if your platform supports it.
http://anthonyvirtuoso.com/public/dokuwiki/doku.php/projects:multiplexreceiverepoll
@jfawcett - select on more than ~50 FDs comes with a fairly significant CPU hit depending on how often you actually perform the select. In my comment above that sample class was originally using select but after seeing the CPU cost (valgrind w/callgrind) I switched to epoll. But certainly select is a valid option.
100 sockets isn't that many. You could go to all the trouble of using something like epoll(), but for this case I'd just set up a single FD_SET with all the sockets, select() on the entire set, then check each one, and process them in sequence. If I had to do something that was potentially time-consuming, I'd use a thread pool for the message handlers.
Indy is your best choice : 1000 clients are not that much : I did develop a server that had to serve 4-5 k clients and it's working as a charm.
--> As for the clients list, you could loop through the TThreadList member of TidTCPServer (version 9.0) that stores all the "alive" threads, each thread is "equivalent" to a client connection, although threads could outlive a client's connection, but you could fix this by setting an appropriate connection's timeout value. If you want you could also maintain your own Clients' List (inherit from TList for instance or create a Generics.Collection): you would add the client info's after the onConnect event (tidPeerThread class exposes all the client infos: IP...)
You would then loop through this list periodically and check for alive connections (ping command like) and kill/delete all zombies.
[indy documentation] Event handler for peer thread connection attempts.
property OnConnect: TIdServerThreadEvent;
Description
OnConnect is an event handler for TIdServerThreadEvents. OnConnect occurs when a TIdPeerThread attempts to connect to a TIdTCPServer.
OnConnect receives AThread as a parameter, representing the TIdPeerThread thread that is requesting the connection.
Assign a TIdServerThreadEvent event handler procedure to OnConnect. [/indy documentation]
for each client, it need to receive and send data based on it's client status : --> check the chat client and server demo source code for a detailed example.
Prefer to work as service with GUI to manage it : you could develop a service application that would log all of its activity in a DB and a second app that would access that db and show all available stats (clients number...).
and here are the links to Indy 9.0 (sources and documentation) : http://www.indyproject.org/downloads/Indy_9_00_14_src.zip http://www.indyproject.org/downloads/Indy-9-0-Help-WinHelp.zip
And here is an Indy book although I don't think you would need it after reading the documentation: Indy in depth : http://www.atozed.com/Indy/Book/index.EN.aspx
Look here for a good tutorial : http://www.devarticles.com/c/a/Delphi-Kylix/Creating-Chat-Application-with-Borland-DelphiIndy-The-Client/
Good Luck