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 :

blocage de la fonction : send


Sujet :

Réseau C

  1. #1
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 382
    Points
    5 382
    Par défaut blocage de la fonction : send
    Bonjour,

    j'ai un problème mon programme, après avoir tout analysé, je pense que la fonction send se bloque. Ma socket est toujours active les messages arrivent toujours mais plus rien ne sort.
    Quelqu'un a-t-il déjà rencontré ce problème ?

    Merci

    Olivier

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Août 2005
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2005
    Messages : 142
    Points : 127
    Points
    127
    Par défaut
    Des fois ça bloque oui

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 129
    Points
    28 129
    Par défaut
    Bonjour,

    Essaie de décrire plus précisément ton problème (type de sockets, ...), et poste un code minimal (et cependant compilable), et explique ce qui te permet de croire que c'est sur l'appel ) la fonction send() que ton prgramme se bloque.

  4. #4
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 382
    Points
    5 382
    Par défaut
    Je reprends un code existant et j'ai un peux de mal avec les fonction FD_xxx.

    Le code est en peu en vrac, si peronne ne peut m'aider c'est pas grave, je vais essayer de voir en créant des threads pour éviter de bloquer tout le système.

    Difficile d'envoyer un code compilable à moins d'envoyer les fichiers.

    Voici la fonction en question où se trouve le send:
    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
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    __DLL_EXPORT int EmClient(short Appl, char * BufEm, int LgEm)
    {
    	fd_set set;
    	int cr;
    	int lgB;
    	char * BufDon;
     
        int rv;		// For return values from socket library functions
     
    	if(SocketApplet[Appl] == 0) {
    		if( Appl == 0 ) {
    			printf("EmClient fictif : %s\n", BufEm );
    			return 0;
    		}
    		return(-1);
    	}
     
    	if(!(BufEm == NULL || LgEm == 0))
    	{
    		// on Allour un buffer un peu plus grand que ce qui est
    		// passé pour ajouter '}'
    		if( ! (BufDon = (char *)malloc( sizeof(char) * (LgEm + 2) )) ) {
    			ErreurPlus( 0, MEM_ALLOC, 0, "Noyau|ServeurCh|EmClient : allocation mémoire impossible");
    			return 0;
    		}
     
    		/* envoie les donnees au client */ 
    		FD_ZERO(&set);  
    		FD_SET(	SocketApplet[Appl], &set);
    		memcpy( BufDon, BufEm, LgEm);
    		*(BufDon + LgEm) = '}';
    		*(BufDon + LgEm + 1) = 0;
    		lgB = LgEm + 1 ;
     
    		rv =0;
    		while (rv<lgB)
    		{
    			cr = select(0, NULL, &set, NULL, NULL);
    			if(cr == SOCKET_ERROR) {
    				printf("SOCKET ERROR\n");
    				exit(0);
    			}
    			lgB -= rv;
    			BufDon += rv;
    			rv = send( SocketApplet[Appl], BufDon, lgB, 0 );
    			//		printf("EMIS: %s\n", BufDon);
    			/* XXXX si client absent on ferme la socket  */
    			if( rv == -1)
    			{
    				closesocket(SocketApplet[Appl]);
    				SocketApplet[Appl] = 0;	
    				free( BufDon );
    				return 0;
    			}
    		}
     
    		free( BufDon );
     
    	}
        return(0);
    }
     
     
    Voici la fonction d'écoute :
    SOCKET Ecoute(int *unused_arg)
    {
     
    	static fd_set fd_lire;		/* variables utilisees par le select */
     
    #ifdef TRACEF
    	TraceFF( TRACE_LEVEL_3,"Thread 0x%x : %s ", 
    			 GetCurrentThreadId(), "ServeurCH-Ecoute");
    #endif
     
    	while (1)
    	{
    		int j;
     
    		FD_ZERO (&fd_lire);	/* mise a zero de la zone */
    		FD_SET (mySock, &fd_lire);	/* initialisation de la socket d'ecoute */
    		for ( j=1; j< MAXREQ; j++)
    		{
    			if ( SocketApplet[j])
    			{
    				FD_SET (SocketApplet[j], &fd_lire);
    			}
    		}
    		select (FD_SETSIZE, &fd_lire, NULL, NULL, NULL);
    		if (FD_ISSET (mySock, &fd_lire))
    		{
    			// il y une demande de connexion
    			int i;
     
    			// Recherche un un epmlacemnt libre
    			for(i=1; SocketApplet[i] != 0; i++);
     
    			if(i != MAXREQ)
    			{
    				/* structure adresse du client demandeur d'ouverture */
    				static   struct sockaddr_in sac;
     
    				int sacSize = sizeof(sac);	// Size of sockaddr_in structures
     
    				SocketApplet[i]  = accept( mySock, (struct sockaddr *)(&sac), &sacSize );
    				memcpy(&StrAdd[i], &sac, sizeof(sac));
    #ifdef TRACEF
    				TraceF(TRACE_LEVEL_1, "ServeurCh - Acceptation : SocketClient %d, Instance %d\n", SocketApplet[i], i);
    #endif
    				if( SocketApplet[i] == -1 )
    				{
    					SocketApplet[i] = 0;
    #ifdef TRACEF
    					TraceF(TRACE_LEVEL_0, "ServeurCh - Acceptation : ERROR on accept n°%d\n", WSAGetLastError());
    #endif
     
    				} 
     
    #ifdef TRACEF
    				TraceF(TRACE_LEVEL_1, "ServeurCh - Acceptation : Connection accepted: socket handle %d - From: %08lX\n", 
    					SocketApplet[i] , ntohl( sac.sin_addr.s_addr ));
    #endif
    				FD_SET (SocketApplet[i], &fd_lire);	/* initialisation de lire */
     
    			}
    		}
    		else
    		{
    			int numClient;
     
    			// regarder pour quelle socket on a un message 
    			for ( numClient=1; numClient< MAXREQ; numClient++)
    			{
    				UNMSG Msg;
     
    				if ( SocketApplet[numClient])
    				{
    					if (FD_ISSET (SocketApplet[numClient], &fd_lire))
    					{
    						char	BufRecO[1000];
    						int lgTot;
     
    						lgTot = recv( SocketApplet[numClient],  BufRecO, sizeof(BufRecO), 0 );
     
    						// si rupture du client on ferme en emetant comme si 
    						// c'était le client qui avait demandé la rupture.
    						if( (lgTot == SOCKET_ERROR) || (lgTot == 0))
    						{
    #ifdef TRACEF
    							TraceF(TRACE_LEVEL_0, "ServeurCh|Ecoute : ERROR %d for RecClient %d\n", 
    								lgTot, SocketApplet[numClient]);
    #endif
    							sprintf( Msg.Ch, "?POSTEOP?DECONNEXION?" );
    							Msg.Instance = numClient;
    							Msg.SiteAppelant = Site_Courant;
    							Emission_Msg(Site_Courant, T_UTILOBJ, OB_REDIRECT_RMICALLS, &Msg, sizeof(Msg));
    							sprintf( Msg.Ch, "?HWBR?LOGOUT?" );
    							Msg.Instance = numClient;
    							Msg.SiteAppelant = Site_Courant;
    							Emission_Msg(Site_Courant, T_UTILOBJ, OB_REDIRECT_RMICALLS, &Msg, sizeof(Msg));
     
    							FD_CLR (SocketApplet[numClient], &fd_lire);	/* initialisation de lire */
    							closesocket(SocketApplet[numClient]);
    							SocketApplet[numClient] = 0;
     
    						}
    						else
    						{
    							int i;
    							char szMsg[1000];
     
     
    							BufRecO[lgTot] = '\0';	// pour transdormer en chaine
     
    							strcat ( MsgRecuClient[numClient], BufRecO);
    #ifdef TRACEF1
    							memset(szMsg, 0, 1000);
    							for(i=0;i<lgTot;i++)
    							{
    								sprintf(szMsg,"%s %d", szMsg, MsgRecuClient[numClient][i]);
    							}
    							TraceF(TRACE_LEVEL_0, "ServeurCh|Ecoute : message <%s>", szMsg);
    #endif
    							// rechercher si on a le caractere '}'
    							i = 0;
    							while (i<strlen(MsgRecuClient[numClient]))
    							{
    								if ( MsgRecuClient[numClient][i] == '}')
    								{
    									UNMSG Msg;
     
    									/* on prepare le message pour l'objet terminal */
    									memset( Msg.Ch, 0, sizeof(Msg.Ch));
     
    									memcpy( Msg.Ch,
    											MsgRecuClient[numClient],
    											i+1);
     
    									Msg.Instance = numClient;
    									Msg.SiteAppelant = Site_Courant;
     
    #ifdef TRACEF1
    									TraceF( TRACE_LEVEL_3,"Noyau|Ecoute - Buffer a traiter : <%s>", Msg.Ch);
    #endif
    									Emission_Msg(Site_Courant, T_UTILOBJ, OB_REDIRECT_RMICALLS, &Msg, sizeof(Msg));
     
    									// supprimer la partie de buffer traitée
    									memmove( MsgRecuClient[numClient],
    											 &MsgRecuClient[numClient][i+1],
    											 LEN_BUFFER-i-1);
    									i=0;	// reinit indice au debut du buffer
    								}
    								else
    									i++;
     
    							}
    						}
    					}
    				} // End for analyse socket
    			}
    		}
    	}
    }
     
    Et la fonction d'init :
    nt  InitSv(int Port, MOT Site)
    {
    	MOT_NS i;
    	struct sockaddr_in mySAddr;	// Socket address structure for server
     
    	#ifdef WIN32
    	WSADATA wsaData;		// Windows socket library data structure
    	#endif
        int rv;		// For return values from socket library functions
     
    /* on initialise la table des sockets applets */
        for(i=0; i < MAXREQ; i++)
    		SocketApplet[i] = 0;	
     
     
    	#ifdef WIN32
    /* Recup de site local */
    	Site_Courant = Site;
     
     
        rv = WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
     
        fprintf(stderr, "WSAStartup() returns %d\n", rv );
        if( rv == -1 )
            fprintf(stderr, "WSAGetLastError() returns %d\n", WSAGetLastError() );
    	#endif
     
     
        mySock = socket( AF_INET, SOCK_STREAM, PF_UNSPEC );
        fprintf(stderr, "Server socket() call returns %d\n", mySock );
        if( mySock == INVALID_SOCKET )
          {
    		#ifndef WIN32
    		fprintf(stderr, "Erreur Socket returns %d\n",  errno);
    		#else
            fprintf(stderr, "WSAGetLastError() returns %d\n", WSAGetLastError() );
    		#endif
            return -1;	// Failure to create socket
          }
     
     
     
        mySAddr.sin_family = AF_INET;	// Internet protocol being used
        mySAddr.sin_addr.s_addr = htonl( INADDR_ANY );    // Accept any client
        mySAddr.sin_port = htons((MOT_NS)Port);	// Port number we will listen on
     
     
     
        rv = bind( mySock, (struct sockaddr *)(&mySAddr), sizeof mySAddr );
     //  fprintf(stderr, "bind() returns %d\n", rv );
        if( rv == -1 )
    	{
    		#ifndef WIN32
    		fprintf(stderr, "Erreur Bind returns %d\n",  errno);
    		#else
            fprintf(stderr, "WSAGetLastError() returns %d\n", WSAGetLastError() );
    		#endif
            return -1;	// Failure to create socket
    	}
     
     
        rv = listen( mySock, 5 );
    	TraceF(TRACE_LEVEL_0,"Socket opened for IHM pour site %d, Port %d", Site, Port);
        fprintf(stderr, "listen() returns %d\n", rv );
        if( rv == -1 )
    	{
    	#ifndef WIN32
    	fprintf(stderr, "Erreur Listen returns %d\n",  errno);
    	#else
            fprintf(stderr, "WSAGetLastError() returns %d\n", WSAGetLastError() );
    	#endif
        return -1;	// Failure to create socket
    	}
      return(0);

  5. #5
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 129
    Points
    28 129
    Par défaut
    Une première remarque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
          /* envoie les donnees au client */
          FD_ZERO(&set); 
          FD_SET(   SocketApplet[Appl], &set);
          memcpy( BufDon, BufEm, LgEm);
          *(BufDon + LgEm) = '}';
          *(BufDon + LgEm + 1) = 0;
          lgB = LgEm + 1 ;
     
          rv =0;
          while (rv<lgB)
          {
             cr = select(0, NULL, &set, NULL, NULL);
             if(cr == SOCKET_ERROR) {
    Est-il absolument normal de faire un select dont le premier paramètre soit 0, sachant que ce nombre est la valeur du plus grand des trois descripteurs, +1 ?

    Ici, tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          FD_SET(   SocketApplet[Appl], &set);
    Donc ton premier paramètre de select devrait être :
    Je ne pense pas que ce soit la source de ton prblème, mais ca peut déjà aider.

  6. #6
    Expert confirmé Avatar de fregolo52
    Homme Profil pro
    Développeur C
    Inscrit en
    Août 2004
    Messages
    2 366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Août 2004
    Messages : 2 366
    Points : 5 382
    Points
    5 382
    Par défaut
    Merci, je vais corriger ce problème, même ce n'est pas la source de mon problème c'est quand même une erreur de développement.

    Merci

Discussions similaires

  1. [Mail] fonction send Email
    Par marquito dans le forum Langage
    Réponses: 2
    Dernier message: 15/06/2007, 12h41
  2. [TCP] Taille de buffer, et fonction send()
    Par phraides dans le forum Développement
    Réponses: 4
    Dernier message: 03/06/2007, 15h45
  3. Réponses: 4
    Dernier message: 23/05/2007, 10h12
  4. blocage sur la fonction close()
    Par crischprolch dans le forum C
    Réponses: 3
    Dernier message: 23/01/2007, 14h28
  5. Question sur les fonctions "send()" et "recv(
    Par damien99 dans le forum MFC
    Réponses: 6
    Dernier message: 10/02/2006, 21h47

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