IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Services Windows Discussion :

Service windows et serveur tcp


Sujet :

Services Windows

  1. #1
    Inactif  
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 26
    Points : 20
    Points
    20
    Par défaut Service windows et serveur tcp
    Bonjour,

    J'ai développé un serveur TCP qui fonctionne parfaitement lorsqu'il est appelé depuis un projet winform. Le but est que ce serveur TCP soit utilisé par un service windows. J'ai intégré ce serveur dans un projet de type DLL, DLL que j'utilise par la suite dans mon projet de service windows... Tout fonctionne parfaitement sauf que... quand je démarre mon service (installé au préalable par installutil monservice) depuis le gestionnaire de service la barre de progression du lancement du service est très lente et me renvoie un
    erreur 1053 : le service n'a pas répondu assez vite à la demande de lancement ou de controle.
    Cela dit étrangement tout fonctionne parfaitement par la suite, le service est bien démarré et le serveur TCP fonctionne(les trames provenant du réseau apparaissent dans le log), seul problème je ne peux plus arrêter mon service depuis le gestionnaire de service car toutes les taches sont grisées de plus le lancement de celui-ci a été très long et c'est soldé par cette erreur 1053...

    Merci d'avance pour votre aide.

    Le service windows :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.ServiceProcess;
     
    namespace MonService
    {
        class Program : ServiceBase
        {
            public Program()
            {
                this.ServiceName = "MonService";
     
            }
     
            static void Main(string[] args)
            {
                ServiceBase.Run(new Program());            
            }
     
            protected override void OnStart(string[] args)
            {
                //Appel de StartListening() : lancement du serveur TCP
                MySocketListener.SocketListener.StartListening();
            }
     
            protected override void OnStop()
            {
                base.OnStop();
            }
        }
    }
    Le serveur TCP :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
     
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Configuration;
    using MyTools;
    using log4net;
     
    namespace MySocketListener
    {
        public static class SocketListener
        {
            static String content=string.Empty;
     
            private static readonly ILog log = LogManager.GetLogger(typeof(SocketListener)); 
     
            public static ManualResetEvent allDone = new ManualResetEvent(false);
     
            public static void StartListening()
            {
                byte[] bytes = new Byte[1024];
                IPAddress ipAddress = IPAddress.Parse(ConfigurationManager.AppSettings["networkIFCIP"]); // ipHostInfo.AddressList[1];
                IPEndPoint localEndPoint = new IPEndPoint(ipAddress, Int32.Parse(ConfigurationManager.AppSettings["tcpPort"]));
     
                Socket listener = new Socket(AddressFamily.InterNetwork,
                    SocketType.Stream, ProtocolType.Tcp);
                try
                {
                    listener.Bind(localEndPoint);
                    listener.Listen(100);
     
                    while (true)
                    {
                        allDone.Reset();
     
                        Console.WriteLine("Waiting for a connection...");
                        listener.BeginAccept(
                            new AsyncCallback(AcceptCallback),
                            listener); 
                        allDone.WaitOne();
                    }
     
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
     
                Console.WriteLine("\nPress ENTER to continue...");
                Console.Read();
            }
     
            public static void AcceptCallback(IAsyncResult ar)
            {
                allDone.Set();
     
                Socket listener = (Socket)ar.AsyncState;
                Socket handler = listener.EndAccept(ar);
     
                StateObject state = new StateObject();
                state.workSocket = handler;
                handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                    new AsyncCallback(ReadCallback), state);
            }
     
            public static void ReadCallback(IAsyncResult ar)
            {
                content = String.Empty;
     
                StateObject state = (StateObject)ar.AsyncState;
                Socket handler = state.workSocket;
     
                int bytesRead = handler.EndReceive(ar);
     
                if (bytesRead > 0)
                {
                    state.sb.Append(Encoding.GetEncoding("ISO-8859-1").GetString(
                        state.buffer, 0, bytesRead));
                    content = state.sb.ToString();
     
     
                        Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
                            content.Length, content);
                        Send(handler, content);
                        log.Debug("Received : " + Tools.GetCtrlCharFormat(content));
     
                }
            }
     
            private static void Send(Socket handler, String data)
            {
                byte[] byteData = Encoding.ASCII.GetBytes(data);
                handler.BeginSend(byteData, 0, byteData.Length, 0,
                    new AsyncCallback(SendCallback), handler);
            }
     
            private static void SendCallback(IAsyncResult ar)
            {
                try
                {
                    Socket handler = (Socket)ar.AsyncState;
     
                    int bytesSent = handler.EndSend(ar);
                    Console.WriteLine("Sent {0} bytes to client.", bytesSent);
                    log.Debug("Sent     : " + Tools.GetCtrlCharFormat(content));
                    handler.Shutdown(SocketShutdown.Both);
                    handler.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
     
     
            public static int Main(String[] args)
            {
                log.Debug("Lancement de l'application");
                StartListening();
                log.Debug("Arrêt de l'application");
                return 0;
            }
        }
    }

  2. #2
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    C'est pas étonnnant : ton "Start" n'est pas un start mais une boucle d'exécution qui ne termine jamais.

    La méthode OnStart doit démarrer ton service et retourner au SCM pour signaler que le service a démarré sans erreur.

    Or, elle ne retourne jamais, donc le SCM en conclue (à juste titre) que ton service n'a pas répondu et pas démarré correctement.

    Je te suggère que tu lises un tuto sur la programmation de service en .Net car c'est la c'est une application que tu as écrit, pas un service.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Pour faire simple, la solution est de lancer un nouveau thread qui exécute ta méthode StartListening :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            private Thread _thread;
     
            protected override void OnStart(string[] args)
            {
                _thread = new Thread(MySocketListener.SocketListener.StartListening);
                _thread.Start();
            }
    Et pour arrêter le service, tu fais un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            protected override void OnStop()
            {
                base.OnStop();
                MySocketListener.SocketListener.StopRequested = true;
                _thread.Join();
            }
    (StopRequested étant une propriété de ta classe SocketListener, que ta boucle principale vérifie à chaque itération)

  4. #4
    Inactif  
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    Tout d'abord merci à vous deux pour vos réponses.

    Citation Envoyé par Bluedeep Voir le message
    Je te suggère que tu lises un tuto sur la programmation de service en .Net car c'est la c'est une application que tu as écrit, pas un service.
    Je suppose que tu dis ça par rapport a la méthode public static int Main(String[] args) et aux Console.Writeline ? Au départ j'avais écris ce code dans une application et j'ai juste fait un copier/coller de celui-ci et n'ai pas encore fait le ménage notamment concernant certains éléments devenus inutile. J'aurais effectivement du le faire avant de poster mes extraits de code

    Citation Envoyé par tomlev
    Et pour arrêter le service, tu fais un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     protected override void OnStop()
            {
                base.OnStop();
                MySocketListener.SocketListener.StopRequested = true;
                _thread.Join();
            }
    Ta solution fonctionne parfaitement pour le démarrage, je n'ai plus d'erreurs. Par contre pour l'arrêt le service ne s'arrête correctement que si j'envoie un message tcp à mon serveur pendant que je suis en train d'arrêter mon service. Sinon j'ai toujours l'erreur 1053.

    J'ai bien créé la propriété StopRequested et ai remplacé ma boucle while(true) par while(!stopRequested). A dire la vérité je ne comprends pas pourquoi ça ne fonctionne pas car dans la logique ça me semble correct... la méthode StartListening est appelé lors du démarrage du service et la propriété StopRequested est testée à chaque itération donc il devrait sortir de la boucle lorsque StopRequested est modifié de false vers true lors du onStop()...

    Je ne sais pas si cela est une bonne façon de faire mais l'arrêt du service fonctionne correctement si je supprime ces deux lignes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MFFSocketListener.SocketListener.StopRequested = true;
    _thread.Join();
    Qu'en pensez-vous ?


    merci

  5. #5
    Inactif  
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    J'ai vérifié en mode debug, lors de l'arrêt du service la méthode OnStop() est bien appelée et StopRequested passe bien à true mais le service me renvoie l'erreur 1053 sur le _thread.Join().

  6. #6
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    En fait le problème est dans ta boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                    while (!StopRequested)
                    {
                        allDone.Reset();
     
                        Console.WriteLine("Waiting for a connection...");
                        listener.BeginAccept(
                            new AsyncCallback(AcceptCallback),
                            listener); 
                        allDone.WaitOne();
                    }
    Tu appelles la version asynchrone de Accept (ce qui est bien), mais vu que juste derrière tu appelles allDone.WaitOne(), ça bloque à nouveau, et la condition du while n'est pas retestée avant qu'un client se connecte.

    En fait il faudrait que tu mettes un timeout sur le waitone, et que tu boucles jusqu'à ce qu'il renvoie true :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                    while (!StopRequested)
                    {
                        allDone.Reset();
     
                        Console.WriteLine("Waiting for a connection...");
                        listener.BeginAccept(
                            new AsyncCallback(AcceptCallback),
                            listener);
                        while (!StopRequested && !allDone.WaitOne(100));
                    }

  7. #7
    Inactif  
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2011
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2011
    Messages : 26
    Points : 20
    Points
    20
    Par défaut
    Ca parait logique (si j'ai bien tout compris...), il attends une réponse sur le WaitOne pendant 100ms, s'il n'en reçois pas pendant ce laps de temps il se mange le timeout et boucle dans le while imbriqué, StopRequested a été mis à true dans le onstop() et est retesté par la condition de ce while imbriqué donc sortie de la boucle imbriqué puis retest de StopRequest dans le while "parent" et sortie de cette boucle également.

    Parfait ! ça fonctionne à merveille ! merci encore

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [C#] Serveur sous forme d'un service windows
    Par imen-ing dans le forum Services Windows
    Réponses: 0
    Dernier message: 30/03/2011, 21h33
  2. impossible d'installer le service pack 1 de windows 2003 serveur
    Par Jean-Claude Dusse dans le forum Windows Serveur
    Réponses: 5
    Dernier message: 08/03/2010, 21h03
  3. long polling entre service windows et un serveur j2EE
    Par sfaxien dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 23/09/2009, 23h25
  4. [batch] [services windows] état service sur serveur distant
    Par Deadpool dans le forum Scripts/Batch
    Réponses: 3
    Dernier message: 16/03/2009, 17h50
  5. service Windows en client serveur TCP
    Par Dr_shaman dans le forum VB.NET
    Réponses: 1
    Dernier message: 20/06/2008, 09h07

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo