Bâtiment Multi threaded Serveur TCP/IP
Je veux construire un serveur TCP/IP qui sera utilisé jusqu'à 100 clients en même temps, mais toujours pas sûr de savoir comment obtenir commencé.
au moins j'ai besoin du serveur:
- À l'écoute du client, et de stocker tous sur tableau ou une liste.
- pour chaque client, il a besoin de recevoir et d'envoyer des données basée sur son statut de client.
- Le serveur doit mettre à jour la liste des clients quand quelqu'un se connecter ou se déconnecter.
- Préfèrent travailler en tant que service avec interface graphique pour gérer.
Pourrait aider quelqu'un comment obtenir de commencer par ça,j'ai regardé indy échantillon, mais ils n'ont pas les aider, aussi regardé pour la plupart des composants, mais toujours à la recherche.
Comme mentionné dans d'autres questions, si votre nombre de clients est supérieur à 1000, vous pourriez avoir des énormes utilisation de la mémoire, si Indy est mis en place avec un thread par client simultanées. Avec async ou la poursuite en fonction des approches, il est possible de traiter beaucoup plus de connexions avec moins de threads. stackoverflow.com/questions/37185/...
Vous pourriez vouloir vérifier ICS composants par Francois Piette et de les comparer. Certaines personnes trouvent Indy mieux pour eux, certaines personnes trouvent ICS mieux pour eux.
Je pense que le blocage de l'approche est mal fait dans la plupart des cas. Pour avoir un thread actif pendant toute la durée de vie de la session ou de l'objet est tout simplement faux. Vous avez juste besoin d'un taks / pool de threads et séparée pour chaque demande que vous utilisez un fil à partir de ce pool. De cette façon, vous aurez tout autant de threads qu'il y a beaucoup de requête simultanées en cours d'exécution au même moment. Et bonne chance atteignant même 100.
Indy fournit 3 types de programmateurs: basé sur le Thread, Threads, avec un pool de threads, et à base de fibres. Par défaut Indy utilise le simple basé sur le thread du planificateur. Si vous avez besoin d'un pool de threads, tout ce que vous devez faire est d'attribuer un TIdSchedulerOfThreadPool instance de votre IdTCPServer.Planificateur de propriété.
Vous pourriez vouloir vérifier ICS composants par Francois Piette et de les comparer. Certaines personnes trouvent Indy mieux pour eux, certaines personnes trouvent ICS mieux pour eux.
Je pense que le blocage de l'approche est mal fait dans la plupart des cas. Pour avoir un thread actif pendant toute la durée de vie de la session ou de l'objet est tout simplement faux. Vous avez juste besoin d'un taks / pool de threads et séparée pour chaque demande que vous utilisez un fil à partir de ce pool. De cette façon, vous aurez tout autant de threads qu'il y a beaucoup de requête simultanées en cours d'exécution au même moment. Et bonne chance atteignant même 100.
Indy fournit 3 types de programmateurs: basé sur le Thread, Threads, avec un pool de threads, et à base de fibres. Par défaut Indy utilise le simple basé sur le thread du planificateur. Si vous avez besoin d'un pool de threads, tout ce que vous devez faire est d'attribuer un TIdSchedulerOfThreadPool instance de votre IdTCPServer.Planificateur de propriété.
OriginalL'auteur DelphiDev | 2010-02-18
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser le
TidTCPServer
qui est multithread à l'intérieur. Pas besoin de vous pour gérer les threads. Tout est transparent, de sorte que dans la façon dont vous écrivez à la demande d'un client, dans (presque) la même manière que vous l'écrivons pour beaucoup. Voir laOnConnect
événement. Il y a unTidContext
paramètre qui a un TThreadList à l'intérieur. Vous pouvez utiliser cet événement pour s'inscrire/ajouter à vos clients, à votre tableau personnalisé/liste etOnDisconnect
pour enlever les clients.La
OnExecute
événement est déclenché lorsque le serveur reçoit un message. Utiliser ses paramètres afin de lire le message qui est envoyé.Aussi, vous avez besoin un autre application qui sera votre client à l'aide de
TidTCPClient
. Dans cette application vous permettra de définir l'adresse de votre serveur (voir l'Hôte de la propriété) ainsi que le Port qui doit correspondre avec le serveur. Vous devriez appelerConnect
(lorsque le serveur est en cours d'exécution) et pour envoyer des chaînes vous avezSendCmd
méthode. (Voir aussiIOHandler.WriteLn
si vous voulez)Il y a aussi d'autres choses mais je pense que c'est assez pour vous obtenir a commencé. Aussi, vous pouvez poster dans Embarcadero forums dans le .Delphes.Winsock forum où l'Indy membres de l'équipe sont flottant au dessus. Ou peut-être vous pouvez demander directement .Delphes.Et Non Technique, le gars là-bas qui va vous guider.
Une autre approche est DataSnap qui est plus orienté objet couche sur Indy (à ne pas confondre avec DBX), qui donne à votre JSON, REST et autres goodies. Voir pour une petite révision ici.
Le
Execute
événement a comme paramètre leAContext: TidContext
. Si vous avezAContext.Connection
où vous avez suffisamment de méthodes pour envoyer des données au client par exemple.AContext.Connection.SendCmd
. Aussi, vous avez leAContext.Connection.Socket
propriété (IIRC), qui a l'un de ses sous-propriétés de l'adresse IP du client qui a envoyé le message. Vous pouvez l'utiliser comme un "clientID" si vous voulez faire de journalisation etc.OriginalL'auteur John Thomas
Et un autre Delphi bibliothèque option serait synapse qui fournit un cadre simple qui peut facilement être étendu. Il y a un IOCPPool démo disponible dans l'contribué fichiers qui peuvent être d'aide.
Synapse est un cadre de classes que d'une bibliothèque de composants. Il y a une dynamique et active communauté d'utilisateurs qui est prêt à soutenir tous les défis. J'utilise cette bibliothèque en Delphi 2010 sans aucun problème (bien que j'utilise la dernière version de développement de SVN).
Être, car ils ne sont pas des composants, il est très facile d'utiliser les classes de la console simple des applications ou des services windows.
Il ya tout à fait quelques démos dans l'installation par défaut qui devrait l'aider, ainsi que les contribué fichiers. Quand tout le reste échoue, posez votre question ici ou sur la synapse liste de diffusion.
OriginalL'auteur skamradt
Sur une plate-forme Windows, vous êtes probablement mieux éviter de
select
pour un grand nombre de connexions simultanées (100 n'est pas un grand nombre de connexions). Cependant, avirtuos est correct en ce que vous voulez éviter à tout " thread par connexion. L'approche la plus efficace sur Windows est d'utiliser overlapped I/O et I/O Ports d'Achèvement. Cela vous permet de gérer les 10s de milliers de connexions avec un petit nombre de fils (2 ou 3, peut-être).Je n'ai pas de Delphi expérience donc je n'ai aucune idée de comment il est facile d'interagir avec du code C++, MAIS j'ai une connexion C++ I/O Port de fin d'infrastructure de serveur (disponible à partir de ici) qui, au moins, de vous montrer comment le Win32 standard I/O Port de fin d'API travaille. Il pourrait être utile de vous et vous pourriez être en mesure de faire quelque chose de similaire à Delphes.
OriginalL'auteur Len Holgate
Indy est votre meilleur choix : 1000 clients ne sont pas tant que ça : j'ai fait développer un serveur qui devait servir de 4-5 k clients, et il fonctionne comme un charme.
--> Comme pour la liste des clients, vous pouvez faire une boucle par la TThreadList membre de TidTCPServer (version 9.0) qui stocke toutes les "vivants" threads, chaque thread est "équivalent" à un client de connexion, bien que les threads peuvent survivre à un client de connexion, mais vous pouvez résoudre ce problème par l'établissement de la connexion de la valeur de délai d'expiration. Si vous voulez vous pouvez aussi conserver vos propres Clients (Liste d'hériter de TList, par exemple, ou de créer un Génériques.De la Collection): vous devez ajouter l'info client après le logiciel onConnect événement (tidPeerThread classe expose toutes les infos client: IP,...)
Vous serait alors en boucle au travers de cette liste régulièrement et vérifier les connexions (commande ping) et de tuer/supprimer tous les zombies.
[indy documentation]
Gestionnaire d'événements pour les pairs fil de tentatives de connexion.
propriété OnConnect: TIdServerThreadEvent;
Description
OnConnect est un gestionnaire d'événements pour TIdServerThreadEvents. Le logiciel OnConnect se produit lorsqu'un TIdPeerThread tente de se connecter à un TIdTCPServer.
OnConnect reçoit AThread comme un paramètre représentant la TIdPeerThread thread qui demande la connexion.
Attribuer un TIdServerThreadEvent procédure de gestionnaire d'événement pour le logiciel OnConnect.
[/indy documentation]
pour chaque client, il a besoin de recevoir et d'envoyer des données basée sur son statut de client :
--> vérifiez le chat le client et le serveur de démo de code source pour un exemple détaillé.
Préfèrent travailler en tant que service avec interface graphique pour gérer : vous pourriez développer une application de service qui permettrait de connecter l'ensemble de son activité dans une DB et une seconde application qui permettrait d'accès que db et de montrer tous disponibles stats (nombre de client...).
et voici les liens pour Indy 9.0 (sources et de la documentation) :
http://www.indyproject.org/downloads/Indy_9_00_14_src.zip
http://www.indyproject.org/downloads/Indy-9-0-Help-WinHelp.zip
Et voici un Indy livre bien que je ne pense pas que tu en aurais besoin après la lecture de la documentation: Indy en profondeur : http://www.atozed.com/Indy/Book/index.EN.aspx
Regardez ici pour un bon tutoriel :
http://www.devarticles.com/c/a/Delphi-Kylix/Creating-Chat-Application-with-Borland-DelphiIndy-The-Client/
Bonne Chance
OriginalL'auteur M0-3E
100 sockets n'est pas beaucoup. Vous pouvez aller à tous la peine d'utiliser quelque chose comme epoll(), mais pour ce cas, je venais tout juste de mettre en place un seul FD_SET avec tous les sockets, sélectionnez() sur l'ensemble de la série, puis vérifier chacune, et de les traiter dans l'ordre. Si je devais faire quelque chose qui a potentiellement beaucoup de temps, j'aimerais utiliser un pool de threads pour les gestionnaires de messages.
OriginalL'auteur jfawcett
De l'excellent composant des ensembles qui sont utiles pour des situations comme la vôtre (et beaucoup plus) sont kbmMW et RemObjects. Il y a quelques autres bons jeux, aussi, je pense, vous pourriez faire une recherche d'archives ou de poser une question dans Embarcaderos' Delphi thirdpartytools groupe de discussion. Vous pouvez consulter les archives ici:
http://codenewsfast.com/
OriginalL'auteur Herbert Sitz
J'ai récemment rencontré ce problème. Voici un lien vers un exemple C++ à l'aide de EPOLL de gérer des centaines de multidiffusion sockets. Vôtre serait TCP/IP, mais c'est vraiment plus qu'un simple changement.
Qui jamais la méthode que vous choisissez, pour 100+ simultanée sockets/clients, vous souhaitez utiliser un modèle de thread qui s'appuie sur un sondage, sélectionnez, ou préférable epoll si votre plate-forme prend en charge.
http://anthonyvirtuoso.com/public/dokuwiki/doku.php/projects:multiplexreceiverepoll
@jfawcett - sélectionnez sur plus de ~50 FDs est livré avec une assez bonne CPU frappé selon quelle fréquence vous réellement en mesure d'effectuer la sélection. Dans mon commentaire ci-dessus que l'échantillon de la classe était à l'origine à l'aide de select, mais après avoir vu le coût de l'UC (valgrind w/callgrind), je suis passé à epoll. Mais certainement choisir est une option valable.
OriginalL'auteur avirtuos