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

Bibliothèques C++ Discussion :

Communication via Socket TCP


Sujet :

Bibliothèques C++

  1. #1
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut Communication via Socket TCP
    Hello,

    Me basant sur un code de communication via socket, je dois faire une petite modification (dans un premier temps). Le code ci-joint fonctionne parfaitement, dans le cadre d'une connexion UDP:
    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
    #include <netdb.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <iostream>
    #include <fstream>
    #include <string.h>
    #include <stdlib.h>
    #include "protocol.pb.h"
    #include <string>
    #include <cstring>
     
    #define MAX_LINE 100
    // 3 caractères pour les codes ASCII 'cr', 'lf' et '\0'
    #define LINE_ARRAY_SIZE (MAX_LINE+3)
     
    using namespace std;
     
    int main()
    {
     
        //GOOGLE_PROTOBUF_VERIFY_VERSION;
     
        test::Error_Info test_msg;
    /*
        test_msg.set_from(1);
        test_msg.set_to(2);
        test_msg.set_msg("toto");
    */
        test_msg.set_id(1);
        test_msg.set_severity(test::Error_Info_Severity_Severity_MAX);
     
      int socketDescriptor;
      int numRead;
      unsigned short int serverPort;
      struct sockaddr_in serverAddress;
      struct hostent *hostInfo;
      struct timeval timeVal;
      fd_set readSet;
      char buf[LINE_ARRAY_SIZE], c;
     
      cout << "Enter server host name or IP address: ";
     
      memset(buf, 0x0, LINE_ARRAY_SIZE);  // Mise à zéro du tampon
    94.  cin.get(buf, MAX_LINE, '\n');
     
      // gethostbyname() reçoit un nom d'hôte ou une adresse IP en notation
      // standard 4 octets en décimal séparés par des points puis renvoie un
      // pointeur sur une structure hostent. Nous avons besoin de cette structure
      // plus loin. La composition de cette structure n'est pas importante pour
      // l'instant.
      hostInfo = gethostbyname(buf);
      if (hostInfo == NULL) {
        cout << "problem interpreting host: " << buf << "\n";
        exit(1);
      }
     
      cout << "Enter server port number: ";
      cin >> serverPort;
      cin.ignore(1,'\n'); // suppression du saut de ligne
     
      // Création de socket. "AF_INET" correspond à l'utilisation du protocole IPv4
      // au niveau réseau. "SOCK_DGRAM" correspond à l'utilisation du protocole UDP
      // au niveau transport. La valeur 0 indique qu'un seul protocole sera utilisé
      // avec ce socket.
      socketDescriptor = socket(AF_INET, SOCK_STREAM, 0);
      if (socketDescriptor < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      // Initialisation des champs de la structure serverAddress
      serverAddress.sin_family = hostInfo->h_addrtype;
      memcpy((char *) &serverAddress.sin_addr.s_addr,
             hostInfo->h_addr_list[0], hostInfo->h_length);
      serverAddress.sin_port = htons(serverPort);
     
      cout << "\nEntrez quelques caractères au clavier.\n";
      cout << "Le serveur les modfiera et les renverra.\n";
      cout << "Pour sortir, entrez une ligne avec le caractère '.' uniquement\n";
      cout << "Si une ligne dépasse " << MAX_LINE << " caractères,\n";
      cout << "seuls les " << MAX_LINE << " premiers caractères seront utilisés.\n\n";
     
      // Invite de commande pour l'utilisateur et lecture des caractères jusqu'à la
      // limite MAX_LINE. Puis suppression du saut de ligne.
      cout << "Input: ";
      memset(buf, 0x0, LINE_ARRAY_SIZE);  // Zero out the buffer.
      cin.get(buf, MAX_LINE, '\n');
      // suppression des caractères supplémentaires et du saut de ligne
      cin.ignore(1000,'\n');
     
      string data;
     
      test_msg.SerializeToString(&data);
     
      // Arrêt lorsque l'utilisateur saisit une ligne ne contenant qu'un point
      while (strcmp(buf, ".")) {
        // Envoi de la ligne au serveur
        if (sendto(socketDescriptor, data.c_str(), strlen(data.c_str()), 0,
                   (struct sockaddr *) &serverAddress,
                   sizeof(serverAddress)) < 0) {
          cerr << "cannot send data ";
          close(socketDescriptor);
          exit(1);
        }
    /*
      while (strcmp(buf, ".")) {
        // Envoi de la ligne au serveur
        if (sendto(socketDescriptor, buf, strlen(buf), 0,
                   (struct sockaddr *) &serverAddress,
                   sizeof(serverAddress)) < 0) {
          cerr << "cannot send data ";
          close(socketDescriptor);
          exit(1);
        }
        */
     
        // Attente de la réponse pendant une seconde.
        FD_ZERO(&readSet);
        FD_SET(socketDescriptor, &readSet);
        timeVal.tv_sec = 1;
        timeVal.tv_usec = 0;
     
        if (select(socketDescriptor+1, &readSet, NULL, NULL, &timeVal)) {
          // Lecture de la ligne modifiée par le serveur.
          memset(buf, 0x0, LINE_ARRAY_SIZE);  // Mise à zéro du tampon
          numRead = recv(socketDescriptor, buf, MAX_LINE, 0);
          if (numRead < 0) {
            cerr << "didn't get response from server?";
            close(socketDescriptor);
            exit(1);
          }
     
          cout << "Modified: " << buf << "\n";
        }
        else {
          cout << "** Server did not respond in 1 second.\n";
        }
     
        // Invite de commande pour l'utilisateur et lecture des caractères jusqu'à la
        // limite MAX_LINE. Puis suppression du saut de ligne. Comme ci-dessus.
        cout << "Input: ";
        memset(buf, 0x0, LINE_ARRAY_SIZE);  // Mise à zéro du tampon
        cin.get(buf, MAX_LINE, '\n');
        // suppression des caractères supplémentaires et du saut de ligne
        cin.ignore(1000,'\n');
      }
     
      close(socketDescriptor);
      return 0;
    }
    par contre, si je change le SOCK_DGRAM par SOCK_STREAM, le programme "plante" lors de la tentative d'envois:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (sendto(socketDescriptor, buf, strlen(buf), 0,
                   (struct sockaddr *) &serverAddress,
                   sizeof(serverAddress)) < 0) {
          cerr << "cannot send data ";
          close(socketDescriptor);
          exit(1);
        }
    La question est: Que faut-il changer d'autre pour que cela fonctionne? je ne vois pas pourquoi cette fonction "sendto" changerais entre UDP et TCP?

    Merci de vos retour

    Onet

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 470
    Par défaut
    Là, vous passez d'un protocole orienté message (UDP) en un protocole orienté flux (TCP). C'est un peu big-bang comme approche.

  3. #3
    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
    sendto() et son pendant recvfrom() ne fonctionnent que pour les socket UDP.

    Pour les socket TCP, c'est pour le serveur :
    • socket()
    • bind()
    • listen()
    • accept()
    • send()
    • recv()
    • close()
    et pour le client :
    • socket()
    • connect()
    • send()
    • recv()
    • close()
    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
    .

  4. #4
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    OKi,

    Il va donc bien falloir que je passe par la! Ok, tant pis, m'étais dis que je pouvais traverser en ligne droite

    Vais plancher un peu plus sérieusement, du coup. Merci

    Onet

  5. #5
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    (Re)Hello,

    je me permets de supprimer le tag "résolu", afin d'éviter de créer un novueau fil (merci a l'admin qui l'avais mis, mais ce n'était pas un oubli de ma part ).

    Donc voila, j'ai modifié mon code, pour passer en 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
    #define MAX_LINE 100
    // 3 caractères pour les codes ASCII 'cr', 'lf' et '\0'
    #define LINE_ARRAY_SIZE (MAX_LINE+3)
     
    #define CLIENT_PORT 9096
    #define CLIENT_IP "172.20.1.130"
    #define SERVER_PORT 9097
    #define SERVER_IP "172.20.1.130"
     
    using namespace std;
     
    int main()
    {
     
        //GOOGLE_PROTOBUF_VERIFY_VERSION;
     
        test::Error_Info test_msg;
    /*
        test_msg.set_from(1);
        test_msg.set_to(2);
        test_msg.set_msg("toto");
    */
        test_msg.set_id(1);
        test_msg.set_severity(test::Error_Info_Severity_Severity_MAX);
     
      int socketClient, socketServer;
      int numRead;
      struct sockaddr_in serverAddress, clientAddress;
      socklen_t serverAddressLenght, clientAddressLenght;
      struct timeval timeVal;
      fd_set readSet;
      char buf[LINE_ARRAY_SIZE], c;
     
     
     
      memset(buf, 0x0, LINE_ARRAY_SIZE);  // Mise à zéro du tampon
     
     
      // Initialyze clientdress strcuture
      clientAddress.sin_addr.s_addr = inet_addr(CLIENT_IP);
      clientAddress.sin_family = AF_INET;
      clientAddress.sin_port = htons(CLIENT_PORT);
     
      // Create Socket with TCP connection
      socketClient = socket(AF_INET, SOCK_STREAM, 0);
      if (socketClient < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      clientAddressLenght = sizeof (clientAddress);
      connect(socketClient, (struct sockaddr*) & clientAddress, clientAddressLenght);
     
     
      // Initialyze serverAdress strcuture
      serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP);
      serverAddress.sin_family = AF_INET;
      serverAddress.sin_port = htons(SERVER_PORT);
     
      // Create Socket with TCP connection
      socketServer = socket(AF_INET, SOCK_STREAM, 0);
      if (socketServer < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      serverAddressLenght = sizeof (serverAddress);
      connect(socketServer, (struct sockaddr*) & serverAddress, serverAddressLenght);
     
      cout << "\nPress \"Enter\" to send communication\n";
     
      cin.get(buf, 1, '\n');
      // suppression des caractères supplémentaires et du saut de ligne
     
      // Send communication
      string data;
     
      test_msg.SerializeToString(&data);
     
      send(socketClient, data.c_str(), strlen(data.c_str()), 0);
     
      // Receive data
     
     
      serverAddressLenght = sizeof (serverAddress);
      bind(socketServer, (struct sockaddr*) & serverAddress,  serverAddressLenght );
     
      listen(socketServer, 5);
     
     
     
      cout << accept(socketServer, (struct sockaddr*) & serverAddress, & serverAddressLenght);
      recv(socketServer, buf, 1, 0);
      string data_rcv = buf;
     
      cout << "Data recue: " << data_rcv;
    Alors, l'envois se passe bien, je n'ai pas de souci, j'ai bien les informations envoyées, mais le programme en face n'arrive pas à me répondre, il me signale que la connexion est fermée. Et pourtant, je la crée, etc... Mais le programme reste en mode bloquand sur la fonction "accepte". Est-ce que ca vient de la?

    les trames envoyées:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    403    5.531380    172.20.1.103    172.20.1.130    TCP    54281 > 9096 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=7066612 TSER=0 WS=6
    404    5.531853    172.20.1.130    172.20.1.103    TCP    9096 > 54281 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1460 WS=0 TSV=0 TSER=0
    405    5.531882    172.20.1.103    172.20.1.130    TCP    54281 > 9096 [ACK] Seq=1 Ack=1 Win=5888 Len=0 TSV=7066612 TSER=0
    406    5.531918    172.20.1.103    172.20.1.130    TCP    52768 > 9097 [SYN] Seq=0 Win=5840 Len=0 MSS=1460 TSV=7066612 TSER=0 WS=6
    407    5.532145    172.20.1.130    172.20.1.103    TCP    9097 > 52768 [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
    548    10.745379    172.20.1.103    172.20.1.130    TCP    54281 > 9096 [PSH, ACK] Seq=1 Ack=1 Win=5888 Len=4 TSV=7067915 TSER=0
    551    10.931280    172.20.1.130    172.20.1.103    TCP    9096 > 54281 [ACK] Seq=1 Ack=5 Win=65531 Len=0 TSV=197297 TSER=7067915
    552    10.963818    172.20.1.130    172.20.1.103    TCP    9096 > 54281 [RST, ACK] Seq=1 Ack=5 Win=0 Len=0
    554    10.967144    172.20.1.103    172.20.1.130    TCP    9097 > ampr-info [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
    557    11.368777    172.20.1.130    172.20.1.103    TCP    ampr-info > 9097 [SYN] Seq=0 Win=65535 Len=0 MSS=1460
    558    11.368827    172.20.1.103    172.20.1.130    TCP    9097 > ampr-info [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
    564    11.915650    172.20.1.130    172.20.1.103    TCP    ampr-info > 9097 [SYN] Seq=0 Win=65535 Len=0 MSS=1460
    565    11.915677    172.20.1.103    172.20.1.130    TCP    9097 > ampr-info [RST, ACK] Seq=1 Ack=1 Win=0 Len=0
    La trame spécifique à l'envois (on voit bien que le data est envoyé):
    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
     
    No.     Time        Source                Destination           Protocol Info
        548 10.745379   172.20.1.103          172.20.1.130          TCP      54281 > 9096 [PSH, ACK] Seq=1 Ack=1 Win=5888 Len=4 TSV=7067915 TSER=0
     
    Frame 548 (70 bytes on wire, 70 bytes captured)
        Arrival Time: Oct  7, 2009 14:30:35.059683000
        [Time delta from previous captured frame: 0.376081000 seconds]
        [Time delta from previous displayed frame: 5.213234000 seconds]
        [Time since reference or first frame: 10.745379000 seconds]
        Frame Number: 548
        Frame Length: 70 bytes
        Capture Length: 70 bytes
        [Frame is marked: False]
        [Protocols in frame: eth:ip:tcp:data]
        [Coloring Rule Name: TCP]
        [Coloring Rule String: tcp]
    Ethernet II, Src: Dell_c2:0e:1f (00:24:e8:c2:0e:1f), Dst: f2:b7:58:a6:a1:9f (f2:b7:58:a6:a1:9f)
        Destination: f2:b7:58:a6:a1:9f (f2:b7:58:a6:a1:9f)
            Address: f2:b7:58:a6:a1:9f (f2:b7:58:a6:a1:9f)
            .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
            .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default)
        Source: Dell_c2:0e:1f (00:24:e8:c2:0e:1f)
            Address: Dell_c2:0e:1f (00:24:e8:c2:0e:1f)
            .... ...0 .... .... .... .... = IG bit: Individual address (unicast)
            .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default)
        Type: IP (0x0800)
    Internet Protocol, Src: 172.20.1.103 (172.20.1.103), Dst: 172.20.1.130 (172.20.1.130)
        Version: 4
        Header length: 20 bytes
        Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
            0000 00.. = Differentiated Services Codepoint: Default (0x00)
            .... ..0. = ECN-Capable Transport (ECT): 0
            .... ...0 = ECN-CE: 0
        Total Length: 56
        Identification: 0x75ca (30154)
        Flags: 0x04 (Don't Fragment)
            0... = Reserved bit: Not set
            .1.. = Don't fragment: Set
            ..0. = More fragments: Not set
        Fragment offset: 0
        Time to live: 64
        Protocol: TCP (0x06)
        Header checksum: 0x69e4 [correct]
            [Good: True]
            [Bad : False]
        Source: 172.20.1.103 (172.20.1.103)
        Destination: 172.20.1.130 (172.20.1.130)
    Transmission Control Protocol, Src Port: 54281 (54281), Dst Port: 9096 (9096), Seq: 1, Ack: 1, Len: 4
        Source port: 54281 (54281)
        Destination port: 9096 (9096)
        [Stream index: 4]
        Sequence number: 1    (relative sequence number)
        [Next sequence number: 5    (relative sequence number)]
        Acknowledgement number: 1    (relative ack number)
        Header length: 32 bytes
        Flags: 0x18 (PSH, ACK)
            0... .... = Congestion Window Reduced (CWR): Not set
            .0.. .... = ECN-Echo: Not set
            ..0. .... = Urgent: Not set
            ...1 .... = Acknowledgement: Set
            .... 1... = Push: Set
            .... .0.. = Reset: Not set
            .... ..0. = Syn: Not set
            .... ...0 = Fin: Not set
        Window size: 5888 (scaled)
        Checksum: 0xa93a [validation disabled]
            [Good Checksum: False]
            [Bad Checksum: False]
        Options: (12 bytes)
            NOP
            NOP
            Timestamps: TSval 7067915, TSecr 0
        [SEQ/ACK analysis]
            [Number of bytes in flight: 4]
    Data (4 bytes)
     
    0000  08 01 10 02                                       ....
        Data: 08011002
        [Length: 4]
    Par contre, on voit également bien, a partir de la trame 551 que le programme externe recoit un RST, SYN lorsqu'il veut communique.

    Une idée pour régler ce souci?

    Merci.
    Onet

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 470
    Par défaut
    Y a pas un Firewall dans la boucle ?

  7. #7
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Mmm,

    Mon pc est un Ubuntu 9.10, sans firewall, et le pc externe une machine virtuelle WinXP (mais également testé avec un portable sous win XP), donc a priori non, pas de souci de firewall. mais je vérifie quand meme, pas bete...

    Onet

  8. #8
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Non, aucuns souci du coté d'iptables

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination         
     
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination         
     
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    Onet

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

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Et côté XP ?
    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

  10. #10
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Ben, c'est XP qui ecrit sur Ubuntu, donc peu de chance. Mais j'ai également testé par une commande en local, pour tenter de communiquer avec mon system:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    netcat 172.20.1.103 9097
    (UNKNOWN) [172.20.1.103] 9097 (?) : Connection refused
    Donc non, pas un souci de firewall

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par onet Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
      cout << accept(socketServer, (struct sockaddr*) & serverAddress, & serverAddressLenght);
      recv(socketServer, buf, 1, 0);
    accept prend comme premier paramètre le socket d'attente de la connexion (celui du bind/listen) mais retourne une nouvelle socket pour le lien établi. C'est sur cette nouvelle socket que tu dois faire ta réception :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int socket_connectee = accept(socketServer, (struct sockaddr*) & serverAddress, &serverAddressLenght);
    recv(socket_connectee, buf, 1, 0);
    Sauf si tu as un accept bizarroïde qui ne ressemble pas aux sockets BSD.

  12. #12
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Ah ouais, c'est p'tetre bien ca... Pas réalisé...

    je test, et je te redis. Merci

    Onet

  13. #13
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Salut,

    Alors, j'ai bien changé, mais a priori, aucunes différences. Ce que je ne comprends pas, c'est que le accept() soit bloquant. Que le recv() le soit, c'est logique, il attends des infos... Mais le accept() ? Il passe au recv une fois qu'il a recu un paque dessus, c'est ca?

    COmment valider qu'il aie bien son port ouvert, et en attente? Un nmap ne me donne aucunes info, et a priori je n'arrive pas à me connecter dessus, il me dit tj que c'est fermé... Bref, COmment je peux vérifier que ce soit bien ouvert?

    Merci.
    Onet

  14. #14
    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
    On peut voir le code ?
    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
    .

  15. #15
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    C'est celui qui est la-haut. mais je le remets sans souci:
    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
     
    //============================================================================
    // Name        : udp_client.cpp
    // Author      : Lange Olivier
    // Version     :
    // Copyright   : Your copyright notice
    // Description : Hello World in C++, Ansi-style
    //============================================================================
    #include <netdb.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <iostream>
    #include <fstream>
    #include <string.h>
    #include <stdlib.h>
    #include "protocol.pb.h"
    #include <string>
    #include <cstring>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
     
     
    #define MAX_LINE 100
    // 3 caractères pour les codes ASCII 'cr', 'lf' et '\0'
    #define LINE_ARRAY_SIZE (MAX_LINE+3)
     
    #define CLIENT_PORT 9096
    #define CLIENT_IP "172.20.1.130"
    #define SERVER_PORT 9097
    #define SERVER_IP "172.20.1.130"
     
    using namespace std;
     
    int main()
    {
     
        //GOOGLE_PROTOBUF_VERIFY_VERSION;
     
        test::Error_Info test_msg;
    /*
        test_msg.set_from(1);
        test_msg.set_to(2);
        test_msg.set_msg("toto");
    */
        test_msg.set_id(1);
        test_msg.set_severity(test::Error_Info_Severity_Severity_MAX);
     
      int socketClient, socketServer, socketRcv;
      int numRead;
      struct sockaddr_in serverAddress, clientAddress;
      socklen_t serverAddressLenght, clientAddressLenght;
      struct timeval timeVal;
      fd_set readSet;
      char buf[LINE_ARRAY_SIZE], c;
     
     
     
      memset(buf, 0x0, LINE_ARRAY_SIZE);  // Mise à zéro du tampon
     
     
      // Initialyze clientdress strcuture
      clientAddress.sin_addr.s_addr = inet_addr(CLIENT_IP);
      clientAddress.sin_family = AF_INET;
      clientAddress.sin_port = htons(CLIENT_PORT);
     
      // Create Socket with TCP connection
      socketClient = socket(AF_INET, SOCK_STREAM, 0);
      if (socketClient < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      clientAddressLenght = sizeof (clientAddress);
      connect(socketClient, (struct sockaddr*) & clientAddress, clientAddressLenght);
     
     
      // Initialyze serverAdress strcuture
      serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP);
      serverAddress.sin_family = AF_INET;
      serverAddress.sin_port = htons(SERVER_PORT);
     
      // Create Socket with TCP connection
      socketServer = socket(AF_INET, SOCK_STREAM, 0);
      if (socketServer < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      //serverAddressLenght = sizeof (serverAddress);
      //connect(socketServer, (struct sockaddr*) & serverAddress, serverAddressLenght);
     
      cout << "\nPress \"Enter\" to send communication\n";
     
      cin.get(buf, 1, '\n');
      // suppression des caractères supplémentaires et du saut de ligne
     
      // Send communication
      string data;
     
      test_msg.SerializeToString(&data);
     
      send(socketClient, data.c_str(), strlen(data.c_str()), 0);
     
      // Receive data
     
     
      serverAddressLenght = sizeof (serverAddress);
      bind(socketServer, (struct sockaddr*) & serverAddress,  serverAddressLenght );
     
      cout << listen(socketServer, 5) << "\n";
     
     
     
      cout << accept(socketServer, (struct sockaddr*) & serverAddress, & serverAddressLenght);
      recv(socketRcv, buf, 10, 0);
      string dataRcv = buf;
     
      cout << "Data recue: " << dataRcv;
     
     
      close(socketClient);
      close(socketServer);
      return 0;
    }
    Onet
    P.S: il est en mode "dev-debug-test", c'est a dire moche, pas opti et brouillon, mais tant que ca marche pas, dur de faire une version finale
    P.S2: Comme je disais la partie envois fonctionne parfaitement. le souci, c'est que l'autre programme a qui j'envois me retourne une chaine pour confirmer mon envoi, et celle la, je ne la recois jamais, preuve dans le dump réseau effectué!

  16. #16
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Il y autre chose qui me parait bizarre à la relecture de ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
      clientAddressLenght = sizeof (clientAddress);
      connect(socketClient, (struct sockaddr*) & clientAddress, clientAddressLenght);
    Le client ne devrait-il pas se connecter à serverAddress ? Si ce n'est pas le cas et qu'effectivement clientAddress désigne le distant, je trouve les noms de variables mal nommées.

  17. #17
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    En fait, y a 2 étapes:

    1 fois en temps que client, j'envois des informations a un server externe. Comme je travaille en temps que client, j'appel mes variables *client*:
    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
     
      // Initialyze clientdress strcuture
      clientAddress.sin_addr.s_addr = inet_addr(CLIENT_IP);
      clientAddress.sin_family = AF_INET;
      clientAddress.sin_port = htons(CLIENT_PORT);
     
      // Create Socket with TCP connection
      socketClient = socket(AF_INET, SOCK_STREAM, 0);
      if (socketClient < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
      // Send communication
      string data;
     
      test_msg.SerializeToString(&data);
    send(socketClient, data.c_str(), strlen(data.c_str()), 0);
    Et juste après, je me place en mode "server", afin de recevoir la communication en retour de la place du serveur distant. J'appel donc mes variables *server*

    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
      // Initialyze serverAdress strcuture
      serverAddress.sin_addr.s_addr = inet_addr(SERVER_IP);
      serverAddress.sin_family = AF_INET;
      serverAddress.sin_port = htons(SERVER_PORT);
     
      // Create Socket with TCP connection
      socketServer = socket(AF_INET, SOCK_STREAM, 0);
      if (socketServer < 0) {
        cerr << "cannot create socket\n";
        exit(1);
      }
     
      // Receive data
     
     
      serverAddressLenght = sizeof (serverAddress);
      bind(socketServer, (struct sockaddr*) & serverAddress,  serverAddressLenght );
     
      cout << listen(socketServer, 5) << "\n";
     
     
     
      cout << accept(socketServer, (struct sockaddr*) & serverAddress, & serverAddressLenght);
      recv(socketRcv, buf, 10, 0);
      string dataRcv = buf;
     
      cout << "Data recue: " << dataRcv;
    De plus, je suis obligé de faire ainsi, car en temps que client j'écris sur le port 9096, et en temps que server, je recois sur le port 9097

    Est-ce plus clair? Complétement faux? merci.
    Onet

  18. #18
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Bon ben je trouve que les noms peuvent porter à confusion. Mais c'est visiblement pas de là que vient le problème.
    La séquence
    Clt -> SYNC -> Srv
    Clt <- RST,ACK <- Srv
    dénote aussi qu'il n'y a personne en écoute côté serveur. Donc question bête : est-tu sûr de ton n° de port TCP ?

  19. #19
    Membre éclairé
    Avatar de onet
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    365
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : Suisse

    Informations forums :
    Inscription : Décembre 2002
    Messages : 365
    Par défaut
    Ben, a priori oui, vu que si je fais un filtre dans wireshark, c'est bien ce port qu'il contacte. Et de mon coté, je l'ai bien conf de cette facon, donc ca devrait etre OK?

    Donc je pige vraiment, mais alors vraiment pas .

    Un moyen de vérifier que ce port soit bien ouvert et en écoute ?

    Onet

  20. #20
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    9097 c'est le port sur lequel écoute ton application. Donc quels sont les résultats de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bind(socketServer, (struct sockaddr*) & serverAddress,  serverAddressLenght );
    cout << listen(socketServer, 5) << "\n";
    cout << accept(socketServer, (struct sockaddr*) & serverAddress, & serverAddressLenght);
    bind devrait retourner 0
    listen devrait retourner 0
    Tu n'as pas changer accept ? accept devrait retourner une nouvelle socket si réussite ou -1 si erreur.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. reperer deconnexion lors d'une copie de fichier via socket tcp
    Par dumoulex dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 23/06/2011, 14h57
  2. [WM15] Communication via sockets
    Par fucce dans le forum Windev Mobile
    Réponses: 5
    Dernier message: 23/02/2010, 18h51
  3. Communication par socket TCP entre module windows et linux
    Par =o0 MOH =0o= dans le forum Réseau
    Réponses: 2
    Dernier message: 29/03/2007, 17h04
  4. python & flash : communication via socket -> Null byt
    Par arcane14 dans le forum Réseau/Web
    Réponses: 3
    Dernier message: 30/01/2006, 21h19

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