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

Réseau C Discussion :

Le serveur arrête la réception + désynchronisation


Sujet :

Réseau C

  1. #61
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Tout ça je le connais et je l'ai fais , ce que je comprend pas c'est l'algorithme,quand commuter quand on a besoin d la semaphore, où l'appeler.

    C'est l'algo que je ne comprend pas.

  2. #62
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Au début, l'acquisition SPI prends les DEUX sémaphores, et ENSUITE, le thread d'envoi TCP/IP essaie de prendre le premier (ce qui va le bloquer, bien sûr).

    Une fois le premier buffer rempli, le SPI lâche le sémaphore du premier buffer, ce qui permet au thread d'envoi d'avoir la main dessus. Une fois les données envoyées, le thread d'envoi lâche le sémaphore, et attends le second (normalement, il est encore bloqué par l'acquision SPI).
    A chaque fois que le buffer est plein, le thread SPI doit effectuer les actions suivantes :
    • Prendre l'AUTRE sémaphore, éventuellement avec un timeout négatif pour vérifier s'il est libre (s'il ne l'est pas => erreur critique).
    • Relâcher le sémaphore courant (=> libère le thread TCP/IP en attente dessus).
    • Acquérir les données jusqu'à remplissage du buffer.


    Pour le thread TCP/IP, c'est la séquence suivante :
    • Prendre le sémaphore courant (=> on se retrouve bloqué, il est pris par l'acquisition SPI).
    • Une fois débloqué, envoyer les données sur le réseau jusqu'à vider le buffer.
    • Libérer le sémaphore courant.
    • Prendre l'autre (=> bloqué, normalement).
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  3. #63
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Merci infiniment , c'est ce que je faisai aussi , sauf que j'ai pas envi de taper des lignes de codes et de ne pas savoir les erreurs proviennent d'où surtout dans une programmation qui me fait perdre !!

    Merci

  4. #64
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Voilà quelques bouts de code pour assurer les échanges de buffers :
    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
    int Current = 0 ;
    void* Buffers[2] ;
    int Semaphores[2] ;
    
    // Récupération du buffer/sémaphore courant.
    Buffers[Current] = .... ;
    Semaphores[Current] = .... ;
    
    // Récupération de l'AUTRE buffer/sémaphore.
    Buffers[1-Current] = .... ;
    Semaphores[1-Current] = .... ;
    
    // Changement de buffer courant.
    // A ne faire QUE lorsque l'acquisition SPI possède les DEUX sémaphores !!!!
    Current = 1 - Current ;
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #65
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Voila quelque lignes de code que j'ai fait si tu peu jeter un coup d 'oeil je me suis juste occupe de l'envoi pour le moment :

    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
    while(1)
      	{
     
      		if (T->Established() == 1)
       	{  // recuperer les buf/semaphore
     
            Buffers[Current] =data1;
            Semaphores[Current] =semID1 ;
            Buffers[1-Current] = data2;
            Semaphores[1-Current] =semID2;
            // envoi
            T->Send(Buffers[Current],8*3,Semaphores[Current]);
            //echnage de buffer semaphore
            Current = 1 - Current ;
     
         }
    Code de la fonction send :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    short cSocket::Send(unsigned char * bufptr, USHORT bufLen,int far *sem)
    {  int result;
        RTX_Reserve_Sem(*sem,0);
        result=send ( sd, bufptr, bufLen, MSG_DONTWAIT, &error );
        RTX_Free_Sem(*sem);
     
        //if (result==-1) established = 0;   //si l'envoi echoue on ferme la connection
        return result;
    }

  6. #66
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Bon je crois je suis énormément perdu la :

    Tu dis que AU DEBUT il faut que le SPI reserve les deux semaphore , comment alors faire sachant que mon SPI fonctionne sur interruption externe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void main()
    {
     //installation de l'interruption
     while(1)
    {
      if(connected)
      //envoi
    }
    }
    Dans le main je ne sais pas comment faire le "AU DEBUT", ni l'echange de buffers puisque comme j'ai dit le SPI est en interruption.
    Donc en gros je te demande stp qu'est ce que je dois mettre dans les fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void huge Config_SPI_HW::ReadWriteBlock(unsigned char *rbuffer,unsigned char *wbuffer)  //Read/Write 8 Bytes
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    short cSocket::Send(unsigned char * bufptr, USHORT bufLen)
    qu'est ce que le main doit contenir et qu'est ce que le thread envoi et l'interruption vont contenir???

    Merci

  7. #67
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Salut j'attend toujours ta réponse , en attendant je te file mon pseudo code pour voir si c'est ce qu'il faut faire :

    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
     
    unsigned char data1[8*3];              // les deux buffer
    unsigned char data2[8*3];
     
    unsigned char zz=0x00;
    unsigned char wbuffer[8]={zz,zz,zz,zz,zz,zz,zz,zz};              // pour la fonction de la lecture SPI
     
    int far *semID1;                     		// semaphore for protecting data1 , et data2
    int far *semID2;
    // variable pour l'échange
     
    int Current = 0 ;                             	// variables d'echange cote EVNOI TCP
    void* Buffers[2] ;
    int Semaphores[2] ;
     
    int _Current = 0 ;                    		  //variables d'echange coté SPI
    void* _Buffers[2] ;
    int _Semaphores[2] ;
     
     
    short cSocket::Send(USHORT bufLen)
     
    {		Buffers[Current]=data1;       //recupere buffer et semaphore
    		Semaphores[Current]=semID1 ;
    		Buffers[1-Current] = data2;
    		Semaphores[1-Current] =semID2;
     
    		RTX_Reserve_Sem(Semaphores[Current],0);
    		send ( sd, Buffers[Current], bufLen, MSG_DONTWAIT, &error );
    		RTX_Free_Sem(Semaphores[Current]);
     
        		current=1-current;		//echange de semaphore et buffer.
    }   
     
     
    void huge Config_SPI_HW::ReadWriteBlock()
    {
      spi_waiton_sem_setmode_dyn(SPI_MODE, div);  		//pour synchroniser les esclaves SPI.
     
    		_Buffers[_Current]=data1;       	//recupere buffer et semaphore
    		_Semaphores[_Current]=semID1 ;
    		_Buffers[1-_Current] = data2;
    		_Semaphores[1-_Current] =semID2;
     
    		RTX_Reserve_Sem(Semaphores[Current],0);
    //Lecture SPI
     while(1)
     
          { 	 for (i=0;i<8;i++)
          		{
                         		spi_read_write_dyn(_Buffers[_Current]+i,wbuffer+i,1);
                         		//Introduction de retard
                         		while(ctr-->0);
                         		ctr = 2;
                   		}
     
           }
    		RTX_Free_Sem(_Semaphores[_Current]);   //liberer la semaphore
     
    		_Current =1-_Current;    //echange de buffer semaphore
      spi_release_sem();        // liberer le bus SPI
    }
     
     
     
    main()
     
    {
     
     
      // debut de code 
     
     
    while(1)
    {
    if(connected)
     
     	{    Send(8*3);
     
     	}
    else
    	{
     	// ecoute et réinitialisation de la connection
     
    	} 
     
    }
    Le souci est comment le SPI peut posseder les deux sémaphore tout au début.

    Merci et désolé encore pour le dérangement!

  8. #68
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Déjà, il faut vérifier que le SPI peut bien acquérir les sémaphores tout en étant en IT. Normalement, oui, mais c'est à vérifier quand même.

    Ensuite : au départ, l'acquisition SPI peut parfaitement locker les deux sémaphores parce qu'ils n'appartiennent à personne.

    Enfin : tu ne dois pas échanger les buffers, et encore moins les sémaphores, dans le thread TCP/IP. Seul l'acquisition SPI a le droit de le faire, le thread TCP/IP prenant TOUJOURS le buffer/sémaphore courant.
    Dit autrement, le consommateur (thread TCP/IP) boucle sur un seul et même buffer, c'est le producteur (acquisition SPI) qui est maître des deux buffers et autorise la permutation.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  9. #69
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Comment le TCP/IP doit boucler sur un seul buffer???

    Pour le thread TCP/IP, c'est la séquence suivante :
    Prendre le sémaphore courant (=> on se retrouve bloqué, il est pris par l'acquisition SPI).
    Une fois débloqué, envoyer les données sur le réseau jusqu'à vider le buffer.
    Libérer le sémaphore courant.
    Prendre l'autre (=> bloqué, normalement).
    Prendr l'autre ca veux dire l'autre buffer non!!??

    Ce n'est pas logique si on boucle sur le meme buffer on risque de l'ecraser par l'ecriture SPI a tout moment!!!

    Vraiment je comprend plus rien en ce que tu m'a di c'est un peu contradictoire pour moi,l'envoi doit se fair sur un buffer quand ce buffer est plein l'envoi se fera cette fois sur l'autre , il y'a bel et bien 2 buffer quand meme dans le processus TCP/IP , et apres tu di :

    Enfin : tu ne dois pas échanger les buffers, et encore moins les sémaphores, dans le thread TCP/IP
    Comment ca se fait???

  10. #70
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par ens-lyon Voir le message
    Comment le TCP/IP doit boucler sur un seul buffer???
    Oui, il envoie (par exemple) toujours le contenu du premier buffer.

    Citation Envoyé par ens-lyon Voir le message
    Prendr l'autre ca veux dire l'autre buffer non!!??
    Prendre le SÉMAPHORE de l'autre buffer. Une fois plein, l'acquisition SPI va échanger buffers et sémaphores.

    Citation Envoyé par ens-lyon Voir le message
    Ce n'est pas logique si on boucle sur le meme buffer on risque de l'ecraser par l'ecriture SPI a tout moment!!!
    Mais non. A part sur la première boucle (et encore...), le SPI, lui, remplit systématiquement le SECOND buffer.

    Citation Envoyé par ens-lyon Voir le message
    Vraiment je comprend plus rien en ce que tu m'a di c'est un peu contradictoire pour moi,l'envoi doit se fair sur un buffer quand ce buffer est plein l'envoi se fera cette fois sur l'autre , il y'a bel et bien 2 buffer quand meme dans le processus TCP/IP
    Oui, mais regarde de nouveau le schéma que j'avais indiqué en début de sujet, sur le double buffer : à chaque fois, un des accès est coupé pour un des éléments.

    Le fait de "changer de buffer" signifie que l'on échange les pointeurs des buffers, et des sémaphores associés, lorsque le buffer SPI est plein.

    Citation Envoyé par ens-lyon Voir le message
    Comment ca se fait???
    Parce que le thread TCP/IP est consommateur (= "esclave", si tu préfères). Ce n'est pas lui qui peut décider du taux de remplissage du buffer en cours d'acquisition SPI, mais bel et bien le code d'acquisition SPI lui-même. C'est donc le SPI qui est "maître" des buffers, et qui décide du moment où l'échange se produit.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  11. #71
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Ok ,alors pourquoi tu a expliqué au début que :

    Quand le buffer d'acquisition SPI est plein, tu permutes les deux buffers (en fait, simplement le pointeur sur le buffer), et tu préviens par un sémaphore / mutex / flag global que l'envoi doit se faire sur l'autre buffer

  12. #72
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Citation Envoyé par ens-lyon Voir le message
    Ok ,alors pourquoi tu a expliqué au début que :
    Parce que c'est le principe général : en l'occurrence, tu "préviens" en libérant le sémaphore, ce qui va libérer le thread TCP/IP en attente... Et comme tu viens de permuter les deux buffers, "son" buffer est bien de nouveau plein et prêt à être expédié.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  13. #73
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Voila ma dérniere version du code , tu peux me dire si c'est bon là , sinon tu peux editer le code et mettre des explications dessus , genre des commentaires là où ça marche pas

    Déclarations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int far *semID1;                     		// semaphore for protecting data1 , et data2
    int far *semID2;
    // variable pour l'échange
     
    int Current = 0 ;                             	// variables d'echange cote EVNOI TCP
    void* Buffers[2] ;
    int Semaphores[2] ;
    Code TCP :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    short cSocket::Send(unsigned char * bufptr, USHORT bufLen)
    {  RTX_Reserve_Sem(Semaphores[Current],0); // reserve semaphore courant
     
    	int result = send ( sd, bufptr, bufLen, MSG_DONTWAIT, &error ); // envoi quand il est  débloqué
       RTX_Free_Sem(Semaphores[Current]);      //  Quand le buffer est vidé on libére la sémaphore courante
       if (result==-1)
         established = 0;   //si l'envoi echoue on ferme la connection
     
       return result;
    }
    Code SPI

    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
    void huge Config_SPI_HW::ReadWriteBlock()  			//Read/Write 8 Bytes
    {
      		spi_waiton_sem_setmode_dyn(SPI_MODE, div);  //pour synchroniser les esclaves SPI.
     
    		Buffers[Current]=data1;       				  //recupere buffers et semaphores
    		Semaphores[Current]=semID1 ;
    		Buffers[1-Current] = data2;
    		Semaphores[1-Current] =semID2;
     
    		RTX_Reserve_Sem(Semaphores[Current],0); 	  //réserve le sémaphore courant.
     
    		//Lecture SPI
     		while(1)
     
          { 	 for (i=0;i<8;i++)
          					{   	spi_read_write_dyn(Buffers[Current]+i,wbuffer+i,1);
                         		//Introduction de retard
                         		while(ctr-->0);
                         		ctr = 2;
                   		}
           }
    		RTX_Free_Sem(Semaphores[Current]);   //liberer la semaphore courante.
     
    		Current =1-Current;    //echange de buffer /semaphore
      		spi_release_sem();        // liberer le bus SPI
    }

  14. #74
    Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 43
    Points : 3
    Points
    3
    Par défaut
    Ah j'ai oublié le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while(1)
      	{
     
      	if (T->Established() == 1)
       		{
     
           			T->Send(Buffers[Current],8*3);
     
           		}

    Voilà merci

Discussions similaires

  1. Arrêt d'un serveur multithread
    Par bambou dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 07/07/2010, 16h04
  2. [VBA, Pb serveur mail Exchange] Réception et Sauvegarde
    Par nokolyo dans le forum VBA Outlook
    Réponses: 8
    Dernier message: 01/12/2008, 17h51
  3. [tomcat] lancement/arrêt du serveur
    Par amel666 dans le forum Tomcat et TomEE
    Réponses: 1
    Dernier message: 28/05/2006, 23h55
  4. [DatagramSocket] Pb de réception de messages côté serveur
    Par simsky dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 13/09/2005, 18h41
  5. Notifier l'arrêt du serveur
    Par tintin22 dans le forum Bases de données
    Réponses: 2
    Dernier message: 16/06/2005, 18h16

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