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 :

Souci de binding de socket


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Par défaut Souci de binding de socket
    Salut à tous.

    Alors tout d'abord je tiens à préciser que je suis assez novice en la matière, et après avoir cherché pas mal dans Google la réponse à mon problème, je vous pose la question en désespoir de cause.

    En fait je dois développer deux programmes (démons) sous Fedora qui tournent en parallèle.
    Le démon A doit envoyer des données (contenue dans des fichiers) au démon B. Actuellement, les deux démons tournent sur la même machine mais je veux faire passer les données par des sockets réseau et non par des fichiers, le but final étant que les démons A et B ne soient pas nécessairement sur la même bécane (voire même qu'il y ait plusieur démons A sur différentes machines qui se réfère à un seul démon B sur une autre).

    Pour le moment tout est donc en local.

    Bon, alors le démon A est le client (qui va envoyer les données) et B est le serveur.

    J'ai donc dans le code du démon A, un socket(), bind() et connect() (pour le send etc.. je verrai plus tard car je problème se situe avant).

    J'ai également rajouté un setsockopt(..,SO_REUSEADDR,&on,sizeof(on)) dans le code du démon A.

    Le démon B, dans son code à la création du socket d'écoute, et une fonction select permettant d'avoir plusieurs socket d'échange simultanés. Lorsque je lance le démon B en premier, celui ci se met bien en attente d'une connexion sur le socket d'écoute (enfin j'espère^^).

    Par contre quand je lance le démon A tout seul, celui-ci doit se connecter au 127.0.0.1:5555 (le sock est bindé sur cette adresse et port). Et je n'ai aucune erreur de connexion (même si aucun serveur n'est lancé o_O) !!

    En revanche, si je lance (logiquement) le démon B puis le démon A, le bind du démon A est impossible : j'ai une erreur 98 (adress is already in use), car le socket d'écoute de B est déjà bindé sur 127.0.0.1:5555.

    Alors là je ne sais plus comment faire pour envoyer des données d'un programme à un autre via les socket sur ma machine locale....Y'a un truc que je n'ai pas compris dans tout ce bouzin!!

    Merci de votre aide, et désolé pour la lecture.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mayhem555 Voir le message
    En fait je dois développer deux programmes (démons) sous Fedora qui tournent en parallèle. <...>
    Montre ton code. On ne peut pas deviner quelles erreurs tu as faites...

  3. #3
    Membre confirmé Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Par défaut
    Bonsoir et désolé

    Voici le code client (une partie du démon A chargée de se connecter au serveur, l'envoi des données n'est pas encore programmé, du moins convenablement)

    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
     
    int SocketInit (void)  
    { 
     
        int                 sock ; 
        uint16_t            port ;
        //unsigned short int port;	
        struct sockaddr_in  name ; 
        struct in_addr     *addr ;
        char               *hostname ;
        //struct hostent     *hostinfo ;
     
        /* Create the socket. */ 
        sock = socket (AF_INET, SOCK_STREAM, 0) ; 
        if (sock < 0) 
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot open socket: %s (%d)", strerror (errno), errno) ; 
     
        port = AscstrToInt (CfgValue (VALUE_SOCKETPORT)) ;
        hostname = CfgValue (VALUE_SOCKETSERVER) ;
     
     
        /* Give the socket a name. */ 
        name.sin_family = AF_INET; 
        name.sin_port = htons (port); 
     
       if (inet_aton(hostname,addr) == 0)
    	 ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname) ;
     
     
    	name.sin_addr = *addr;
     
        ErrorPrintf (ERROR_DEBUG, "Connect to %s:%u" , inet_ntoa (name.sin_addr), ntohs (name.sin_port) );
    	printf("ON PASSE ICI ==1==\n");
     
    	/*Set socket sock option to reuse local adresses*/
     
    	int option = 1;
    	setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (void*)&option, sizeof(option)) ;
     
        if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) 
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot bind socket %s:%d: %s (%d)", hostname, port, strerror (errno), errno) ;
     
     
    	printf("ON PASSE ICI ==2==\n");
     
        //  if (inet_aton (hostname, &name.sin_addr) == 0)
        //    ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname) ;
     
        //hostinfo = gethostbyname (hostname) ; 
        //if (hostinfo == NULL) 
        //    ErrorPrintf (ERROR_EXIT_SOCKET, "Unknown host %s", hostname) ; 
        //name->sin_addr = (struct in_addr) hostinfo->h_addr; 
     
     
        //name.sin_addr.s_addr = htonl (INADDR_LOOPBACK) ;
        //name.sin_addr.s_addr = htonl (in6addr_loopback) ;
     
     
        // connect socket
        if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
        { 		
    		shutdown (sock, 2);
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot connect socket %s:%d: %s (%d)", hostname, port, strerror (errno), errno) ;
    	}
     
     
    	printf("ON PASSE ICI ==3==\n");
    	shutdown(sock,2);
     
     
    return sock; 
    }
    Les fonctions ErrorPrintf() et la manière d'obtenir les adresse + port (read à partir d'un fichier cfg) sont des fonctions déjà programmées avant mon passage et marchent.

    Voici maintenant le côté serveur (partie du démon B)

    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
    void
    SocketServer ( funcp )
        int (*funcp)() ;
    { 
     
        int			sock, i ; //integers for the socket descriptors
        fd_set 		active_fd_set, read_fd_set ; //declare socket (file) descriptors sets for the select function below 
        struct 		sockaddr_in name, clientname ;  //structures that will contain sockets addresses information (server, and clients)
    	struct 		in_addr     *addr ;
        socklen_t 	size ; 
        static char buffer [LINESIZE] ;
        int    		nbbytes ;
    	int 		port = AscstrToInt (CfgValue (VALUE_SOCKETPORT)) ;
        char 		*hostname = CfgValue (VALUE_SOCKETSERVER) ;
     
     
     
     
        /* Create the listening socket of the server and set it up to accept connections. */
     
    	name.sin_family = AF_INET;
    	name.sin_port = htons (port);
    	if (inet_aton(hostname,addr) == 0)
    	 ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname) ;
     
    	name.sin_addr = *addr;
     
     
    	/* Create the socket. */
    	sock = socket (PF_INET, SOCK_STREAM, 0);
    	if (sock < 0) 
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot open socket: %s (%d)", strerror (errno), errno) ;
     
     
    	/* Give the socket a name (bind) */
      	if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0) 
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot bind socket: %s (%d)", strerror (errno), errno) ; 
     
    	/* End of listening socket creation and binding*/ 
     
     
        if (listen (sock, 1) < 0) 
            ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot listen to socket") ;
     
     
     
        /* Initialize the set of active sockets. */ 
        FD_ZERO (&active_fd_set);     //active_fd_set is initialized to be the empty file descriptor set
        FD_SET (sock, &active_fd_set); //adds "sock" to the socket descriptor set activ_fd_set
     
     
        while (1)  { 
            /* Block until input arrives on one or more active sockets. */ 
            read_fd_set = active_fd_set;
     
     
            if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)  //returns the number of descriptor in which input arrives
                ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot select soket") ;
     
     
     
            /* Service all the sockets with input pending. */ 
            for (i = 0; i < FD_SETSIZE; ++i) {
     
                if (! (FD_ISSET (i, &read_fd_set))) continue;  //descriptor i is not a pending connexion
     
                if (i == sock) { 
                    /* Connection request on original socket. */ 
                    int new; 
                    size = sizeof (clientname); 
     
                    new = accept (sock, (struct sockaddr *) &clientname, &size); 
                    if (new < 0) 
                        ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot accept new connection on soket") ;
     
                    ErrorPrintf (ERROR_INFO, "Server: receive connect from host %s, port %hd.\n", 
                        inet_ntoa (clientname.sin_addr), 
                        ntohs (clientname.sin_port)) ; 
     
                    FD_SET (new, &active_fd_set); //adds "new" to the socket descriptor set activ_fd_set
     
                } else { 
                    /* Data arriving on an already-connected socket. */ 
                    nbbytes = SocketRead (i, buffer, LINESIZE) ;
     
    				/* Nothing is left to reveive on socket i, we close the connexion on i, then we delete from the socket descriptor set*/
                    if (nbbytes < 0) { 
                        close (i); 
                        FD_CLR (i, &active_fd_set) ;
                        continue ;
                    } 
     
                    (*funcp) (buffer, nbbytes) ;
     
                }
     
            }   // for 
        }  // while
     
     
    }

    Ne pretez pas attention au pointeur de fonction ici, ça marche pas même sans.

    Merci de prendre le temps de m'aider en tout cas !

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mayhem555 Voir le message
    Voici le code client (une partie du démon A chargée de se connecter au serveur, l'envoi des données n'est pas encore programmé, du moins convenablement)
    Le code est incomplet. Merci pour les 20 minutes de rétro-conception... Pas que ça à faire...

    Ceci est incohérent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
       struct in_addr *addr;
     
       if (inet_aton (hostname, addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
     
       name.sin_addr = *addr;
    addr n'a jamais été initialisé. Le comportement est indéterminé.

    Tout ce code me parait bien compliqué...

    http://emmanuel-delahaye.developpez.com/reseaux.htm

    Avec ce code
    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
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdarg.h>
     
    #define PORT 23
    #define IP "127.0.0.1"
     
    #define VALUE_SOCKETPORT PORT
    #define VALUE_SOCKETSERVER IP
    #define CfgValue(a) a
    #define AscstrToInt(a) a
     
    #define inet_aton(a, b) 1
     
    typedef unsigned short uint16_t;
    enum
    {
       OK,
       ERROR_EXIT_SOCKET,
       ERROR_DEBUG,
       dummy
    };
     
    static void ErrorPrintf (int err, char const *fmt, ...)
    {
       va_list va;
       va_start (va, fmt);
     
       printf ("err #%d: ", err);
       vprintf (fmt, va);
       printf("\n");
       va_end (va);
    }
     
    int SocketInit (void)
    {
     
       int sock;
       uint16_t port;
     
       struct sockaddr_in name;
       char const *hostname;
     
    /* Create the socket. */
     
       sock = socket (AF_INET, SOCK_STREAM, 0);
       if (sock < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot open socket: %s (%d)",
                       strerror (errno), errno);
     
       port = AscstrToInt (CfgValue (VALUE_SOCKETPORT));
       hostname = CfgValue (VALUE_SOCKETSERVER);
     
    /* Give the socket a name. */
     
       name.sin_family = AF_INET;
       name.sin_port = htons (port);
     
       if (inet_aton (hostname, addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
     
       /* server IP address */
       name.sin_addr.s_addr = inet_addr(hostname);
     
       ErrorPrintf (ERROR_DEBUG, "Connect to %s:%u", inet_ntoa (name.sin_addr),
                    ntohs (name.sin_port));
       printf ("ON PASSE ICI ==1==\n");
     
    /*Set socket sock option to reuse local adresses */
     
     
       int option = 1;
       setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (void *) &option,
                   sizeof (option));
     
       if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot bind socket %s:%d: %s (%d)",
                       hostname, port, strerror (errno), errno);
     
       printf ("ON PASSE ICI ==2==\n");
     
    /* if (inet_aton (hostname, &name.sin_addr) == 0) */
     
    /* ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname) ; */
     
     
    /* hostinfo = gethostbyname (hostname) ; */
     
    /* if (hostinfo == NULL) */
     
    /* ErrorPrintf (ERROR_EXIT_SOCKET, "Unknown host %s", hostname) ; */
     
    /* name->sin_addr = (struct in_addr) hostinfo->h_addr; */
     
     
    /* name.sin_addr.s_addr = htonl (INADDR_LOOPBACK) ; */
     
    /* name.sin_addr.s_addr = htonl (in6addr_loopback) ; */
     
     
    /* connect socket */
     
       if (connect (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
       {
          shutdown (sock, 2);
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot connect socket %s:%d: %s (%d)",
                       hostname, port, strerror (errno), errno);
       }
     
       printf ("ON PASSE ICI ==3==\n");
       shutdown (sock, 2);
     
       return sock;
    }
     
    void client(void)
    {
    int sock = SocketInit ();
     
    }
    int main (void)
    {
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       client ();
    #if defined (WIN32)
       WSACleanup ();
    #endif
       system ("pause");
     
       return 0;
    }
    J'obtiens
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    err #2: Connect to 127.0.0.1:23
    ON PASSE ICI ==1==
    ON PASSE ICI ==2==
    err #1: Cannot connect socket 127.0.0.1:23: No error (0)
    ON PASSE ICI ==3==
    Appuyez sur une touche pour continuer...
    sans serveur.

    Ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       char *hostname = CfgValue (VALUE_SOCKETSERVER);
    est une absurdité dans un serveur. Il faut mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
             /* automatic IP address */
             name.sin_addr.s_addr = htonl (INADDR_ANY);
    Ce code de serveur :
    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
     
    #if defined (WIN32)
    #include <winsock2.h>
    typedef size_t socklen_t;
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #include "ed/inc/sys.h"
     
    #define PORT 23
     
    #define LINESIZE 128
     
    #define VALUE_SOCKETPORT PORT
    #define VALUE_SOCKETSERVER IP
    #define CfgValue(a) a
    #define AscstrToInt(a) a
     
    enum
    {
       OK,
       ERROR_EXIT_SOCKET,
       ERROR_DEBUG,
       ERROR_INFO,
       dummy
    };
     
    static void ErrorPrintf (int err, char const *fmt, ...)
    {
       va_list va;
       va_start (va, fmt);
     
       printf ("err #%d: ", err);
       vprintf (fmt, va);
       printf ("\n");
       va_end (va);
    }
     
    #define SocketRead(a,b,c) recv (a,b,c,0)
     
    void SocketServer (int (*funcp) (void *, int))
    {
     
    /* integers for the socket descriptors */
       int sock, i;
    #if 0
    /* declare socket (file) descriptors sets for the select function below */
       fd_set active_fd_set, read_fd_set;
       struct in_addr *addr;
    #endif
    /* structures that will contain sockets addresses information (server, and clients) */
       struct sockaddr_in name, clientname;
       socklen_t size;
       static char buffer[LINESIZE];
       int nbbytes;
       int port = AscstrToInt (CfgValue (VALUE_SOCKETPORT));
     
    /* Create the listening socket of the server and set it up to accept connections. */
     
       name.sin_family = AF_INET;
       name.sin_port = htons (port);
     
       /* automatic IP address */
       name.sin_addr.s_addr = htonl (INADDR_ANY);
     
    /* Create the socket. */
     
       sock = socket (PF_INET, SOCK_STREAM, 0);
       if (sock < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot open socket: %s (%d)",
                       strerror (errno), errno);
     
    /* Give the socket a name (bind) */
     
       if (bind (sock, (struct sockaddr *) &name, sizeof name) < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot bind socket: %s (%d)",
                       strerror (errno), errno);
     
    /* End of listening socket creation and binding */
     
       if (listen (sock, 1) < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot listen to socket");
     
    #if 0
    /* -ed- cet algo ne peut pas fonctionner avec Windows.) */
     
    /* Initialize the set of active sockets. */
     
    /* active_fd_set is initialized to be the empty file descriptor set */
       FD_ZERO (&active_fd_set);
    /* adds "sock" to the socket descriptor set activ_fd_set */
       FD_SET (sock, &active_fd_set);
     
       while (1)
       {
    /* Block until input arrives on one or more active sockets. */
          read_fd_set = active_fd_set;
     
    /* returns the number of descriptor in which input arrives */
          printf ("before select()\n");
          if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
             ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot select socket");
     
    /* Service all the sockets with input pending. */
     
          for (i = 0; i < FD_SETSIZE; ++i)
          {
             if (!(FD_ISSET (i, &read_fd_set)))
    /* descriptor i is not a pending connexion */
                continue;
     
             if (i == sock)
             {
    /* Connection request on original socket. */
     
                int new;
                size = sizeof (clientname);
     
                new = accept (sock, (struct sockaddr *) &clientname, &size);
                if (new < 0)
                   ErrorPrintf (ERROR_EXIT_SOCKET,
                                "Cannot accept new connection on soket");
     
                ErrorPrintf (ERROR_INFO,
                             "Server: receive connect from host %s, port %hd.\n",
                             inet_ntoa (clientname.sin_addr),
                             ntohs (clientname.sin_port));
     
    /* adds "new" to the socket descriptor set activ_fd_set */
                FD_SET (new, &active_fd_set);
     
             }
             else
             {
    /* Data arriving on an already-connected socket. */
     
                nbbytes = SocketRead (i, buffer, LINESIZE);
     
    /* Nothing is left to reveive on socket i, we close the connexion on i, then we delete from the socket descriptor set */
     
                if (nbbytes <= 0)
                {
                   closesocket (new);
                   FD_CLR (i, &active_fd_set);
                   continue;
                }
     
                /* to upper layer */
                if (funcp)
                {
                   funcp (buffer, nbbytes);
                }
             }
     
    /* for */
          }
    /* while */
       }
    #else
     
    /* faisons simple (mono-client, pour le moment) */
     
       {
          int new;
          size = sizeof (clientname);
     
          new = accept (sock, (struct sockaddr *) &clientname, &size);
          if (new < 0)
             ErrorPrintf (ERROR_EXIT_SOCKET,
                          "Cannot accept new connection on soket");
          else
          {
             ErrorPrintf (ERROR_INFO,
                          "Server: receive connect from host %s, port %hd.\n",
                          inet_ntoa (clientname.sin_addr),
                          ntohs (clientname.sin_port));
     
             int end = 0;
             while (!end)
             {
    /* Data arriving on an already-connected socket. */
     
                nbbytes = SocketRead (new, buffer, LINESIZE - 1);
     
    /* Nothing is left to reveive on socket i, we close the connexion on i, then we delete from the socket descriptor set */
     
                if (nbbytes <= 0)
                {
                   closesocket (new);
                   end = 1;
                }
                else
                {
                   /* to upper layer */
                   if (funcp)
                   {
                      funcp (buffer, nbbytes);
                   }
                }
             }
          }
       }
     
    #endif
     
    }
     
    void data_process (void *p, int size)
    {
       if (p != NULL && size > 0)
       {
          char *s = p;
          s[size] = 0;
     
          printf ("< '%s'\n", s);
       }
    }
     
    int main (void)
    {
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       SocketServer (data_process);
    #if defined (WIN32)
       WSACleanup ();
    #endif
       system ("pause");
     
       return 0;
    }
    Fonctionne avec un client Telnet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    err #3: Server: receive connect from host 127.0.0.1, port 1406.
     
    < 'H'
    < 'e'
    < 'l'
    < 'l'
    < 'o'
    < '
    '
    Appuyez sur une touche pour continuer...
    Mais pas avec le client ci-dessus. Il y a donc un bug dans ce client (ne se connecte pas).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
       if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Cannot bind socket %s:%d: %s (%d)",
                       hostname, port, strerror (errno), errno);
     
       printf ("ON PASSE ICI ==2==\n");
    Ceci ne concerne que le serveur. A supprimer.

    La connexion fonctionne maintenant.
    Client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    err #2: Connect to 127.0.0.1:23
    ON PASSE ICI ==1==
    ON PASSE ICI ==3==
    Appuyez sur une touche pour continuer...
    Serveur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    err #3: Server: receive connect from host 127.0.0.1, port 1558.
     
    Appuyez sur une touche pour continuer...

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Mayhem555 Voir le message
    Bon, alors le démon A est le client (qui va envoyer les données) et B est le serveur.

    J'ai donc dans le code du démon A, un socket(), bind() et connect() (pour le send etc.. je verrai plus tard car je problème se situe avant).

    J'ai également rajouté un setsockopt(..,SO_REUSEADDR,&on,sizeof(on)) dans le code du démon A.
    Cela me parait suspect que le client A ait besoin de binder le socket.
    D'habitude, c'est socket() puis connect(), pas besoin de bind() sauf si tu veux que ton client utilise un port source donné (mais là, c'est pour un besoin très particulier et je ne pense pas que cela soit ton besoin).
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par ram_0000 Voir le message
    Cela me parait suspect que le client A ait besoin de binder le socket.
    D'habitude, c'est socket() puis connect(), pas besoin de bind() sauf si tu veux que ton client utilise un port source donné (mais là, c'est pour un besoin très particulier et je ne pense pas que cela soit ton besoin).
    C'est effectivement le bug que j'ai trouvé dans le client...

    "in code we trust"

  7. #7
    Membre confirmé Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Par défaut
    Salut !

    Merci pour votre aide, je vais essayer de faire les modifs que vous me conseillez.

    Désolé encore pour les 20 minutes de rétro-conception, t'aurais du m'engueuler en me disant de mettre plus de truc plutôt que de te faire chier pendnat 20 minutes Mais merci beaucoup en tout cas !

    Je vous reviens dès que j'ai fait les modifs.

  8. #8
    Membre confirmé Avatar de Mayhem555
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 89
    Par défaut
    j'ai une question

    Ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct in_addr *addr;
     
       if (inet_aton (hostname, addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
     
       name.sin_addr = *addr;
    est incohérent car addr n'est pas initialisée. Comment initialiser ce truc ?

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mayhem555 Voir le message
    j'ai une question

    Ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct in_addr *addr;
     
       if (inet_aton (hostname, addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
     
       name.sin_addr = *addr;
    est incohérent car addr n'est pas initialisée. Comment initialiser ce truc ?
    Lire la doc de inet_aton() qui attend l'adresse d'un struct in_addr.

    Le plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    struct in_addr addr = {0};
     
       if (inet_aton (hostname, &addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
     
       name.sin_addr = addr;
    Ou tout simplement en refléchissant 2 secondes de plus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
       if (inet_aton (hostname, &name.sin_addr) == 0)
          ErrorPrintf (ERROR_EXIT_SOCKET, "Invalid hostname: %s", hostname);
    Quand on peut faire simple, faut pas hésiter...

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 02/10/2009, 15h00
  2. Souci Chargement module DBI - socket.h error
    Par michael.mazuk dans le forum Modules
    Réponses: 1
    Dernier message: 08/06/2007, 21h02
  3. socket : erreur avec bind()
    Par horkets dans le forum Réseau
    Réponses: 11
    Dernier message: 30/10/2006, 11h47
  4. [SOCKET] Fonction bind()
    Par chacal dans le forum Développement
    Réponses: 13
    Dernier message: 19/12/2005, 14h22
  5. Récupérer l'adresse de bind d'un socket
    Par gloode dans le forum Réseau
    Réponses: 4
    Dernier message: 04/02/2005, 10h56

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