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

C Discussion :

question pour "Winsock Client Source Code"


Sujet :

C

  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut question pour "Winsock Client Source 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
     
    #define WIN32_LEAN_AND_MEAN
     
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
     
     
    // Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
    #pragma comment (lib, "Ws2_32.lib")
    #pragma comment (lib, "Mswsock.lib")
    #pragma comment (lib, "AdvApi32.lib")
     
     
    #define DEFAULT_BUFLEN 512
    #define DEFAULT_PORT "27015"
     
    int __cdecl main(int argc, char **argv) 
    {
        WSADATA wsaData;
        SOCKET ConnectSocket = INVALID_SOCKET;
        struct addrinfo *result = NULL,
                        *ptr = NULL,
                        hints;
        char *sendbuf = "this is a test";
        char recvbuf[DEFAULT_BUFLEN];
        int iResult;
        int recvbuflen = DEFAULT_BUFLEN;
     
        // Validate the parameters
        if (argc != 2) {
            printf("usage: %s server-name\n", argv[0]);
            return 1;
        }
     
        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
        if (iResult != 0) {
            printf("WSAStartup failed with error: %d\n", iResult);
            return 1;
        }
     
        ZeroMemory( &hints, sizeof(hints) );
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
     
        // Resolve the server address and port
        iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result);
        if ( iResult != 0 ) {
            printf("getaddrinfo failed with error: %d\n", iResult);
            WSACleanup();
            return 1;
        }
     
        // Attempt to connect to an address until one succeeds
        for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
     
            // Create a SOCKET for connecting to server
            ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, 
                ptr->ai_protocol);
            if (ConnectSocket == INVALID_SOCKET) {
                printf("socket failed with error: %ld\n", WSAGetLastError());
                WSACleanup();
                return 1;
            }
     
            // Connect to server.
            iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
            if (iResult == SOCKET_ERROR) {
                closesocket(ConnectSocket);
                ConnectSocket = INVALID_SOCKET;
                continue;
            }
            break;
        }
     
        freeaddrinfo(result);
     
        if (ConnectSocket == INVALID_SOCKET) {
            printf("Unable to connect to server!\n");
            WSACleanup();
            return 1;
        }
     
        // Send an initial buffer
        iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
        if (iResult == SOCKET_ERROR) {
            printf("send failed with error: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            return 1;
        }
     
        printf("Bytes Sent: %ld\n", iResult);
     
        // shutdown the connection since no more data will be sent
        iResult = shutdown(ConnectSocket, SD_SEND);
        if (iResult == SOCKET_ERROR) {
            printf("shutdown failed with error: %d\n", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            return 1;
        }
     
        // Receive until the peer closes the connection
        do {
     
            iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
            if ( iResult > 0 )
                printf("Bytes received: %d\n", iResult);
            else if ( iResult == 0 )
                printf("Connection closed\n");
            else
                printf("recv failed with error: %d\n", WSAGetLastError());
     
        } while( iResult > 0 );
     
        // cleanup
        closesocket(ConnectSocket);
        WSACleanup();
     
        return 0;
    }
    salut

    j'ai une question pour ce code, pour quoi utiliser ce tester au démarrage de programme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     // Validate the parameters
        if (argc != 2) {
            printf("usage: %s server-name\n", argv[0]);
            return 1;
        }
    ce code ne marche pas a cause de ce teste car quant j'exécute ce code il recevra toujour une valeur différant de 2, (argc = 1 : et argv[0] = le nom de l'exécutable ) donc impossible de marcher ,j'ai besoin de l'aide pour comprendre pour quoi ce teste est utiliser et merci d'avance pour vos réponses

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Le programme se sert de argv[1] comme nom d'hôte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); // ligne 51
    --> http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx

    Il faut appeler le programme en ligne de commande pour pouvoir lui passer des paramètres facilement.

  3. #3
    Membre expérimenté Avatar de Vespiras
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 168
    Par défaut
    Du coup dans ton exemple, si le nombre d'arguments passé à l'exécution de ton programme est différent de 2, il t'écris à la console comment utiliser les arguments.

    argv[n] représentant ton n ième argument
    et argc ton nombre d'argument avec lequel tu as exécuté ton programme.

    exemple :
    tonprog.exe nom_dhote
    argv[0] argv[1]

    argv == 2

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut
    salut et merci pour les réponses mais j'ai rien compris de ce que vous vient me dire , j'ai supprimer ce code pour le coté Client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    // Validate the parameters
        if (argc != 2) {
            printf("usage: %s server-name\n", argv[0]);
            return 1;
        }
    sur le code 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
    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
     
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
     
    #define DEFAULT_BUFLEN 512
    #define DEFAULT_PORT "27015"
     
    int __cdecl main(void) 
    {
        WSADATA wsaData;
        SOCKET ListenSocket = INVALID_SOCKET,
               ClientSocket = INVALID_SOCKET;
        struct addrinfo *result = NULL,
                        hints;
        char recvbuf[DEFAULT_BUFLEN];
        int iResult, iSendResult;
        int recvbuflen = DEFAULT_BUFLEN;
     
     
        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
        if (iResult != 0) {
            printf("WSAStartup failed: %d\n", iResult);
            return 1;
        }
     
        ZeroMemory(&hints, sizeof(hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_PASSIVE;
     
        // Resolve the server address and port
        iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
        if ( iResult != 0 ) {
            printf("getaddrinfo failed: %d\n", iResult);
            WSACleanup();
            return 1;
        }
     
        // Create a SOCKET for connecting to server
        ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
        if (ListenSocket == INVALID_SOCKET) {
            printf("socket failed: %ld\n", WSAGetLastError());
            freeaddrinfo(result);
            WSACleanup();
            return 1;
        }
     
        // Setup the TCP listening socket
        iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            printf("bind failed: %d\n", WSAGetLastError());
            freeaddrinfo(result);
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
     
        freeaddrinfo(result);
     
        iResult = listen(ListenSocket, SOMAXCONN);
        if (iResult == SOCKET_ERROR) {
            printf("listen failed: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
     
        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) {
            printf("accept failed: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
     
        // No longer need server socket
        closesocket(ListenSocket);
     
        // Receive until the peer shuts down the connection
        do {
     
            iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
            if (iResult > 0) {
                printf("Bytes received: %d\n", iResult);
     
            // Echo the buffer back to the sender
                iSendResult = send( ClientSocket, recvbuf, iResult, 0 );
                if (iSendResult == SOCKET_ERROR) {
                    printf("send failed: %d\n", WSAGetLastError());
                    closesocket(ClientSocket);
                    WSACleanup();
                    return 1;
                }
                printf("Bytes sent: %d\n", iSendResult);
            }
            else if (iResult == 0)
                printf("Connection closing...\n");
            else  {
                printf("recv failed: %d\n", WSAGetLastError());
                closesocket(ClientSocket);
                WSACleanup();
                return 1;
            }
     
        } while (iResult > 0);
     
        // shutdown the connection since we're done
        iResult = shutdown(ClientSocket, SD_SEND);
        if (iResult == SOCKET_ERROR) {
            printf("shutdown failed: %d\n", WSAGetLastError());
            closesocket(ClientSocket);
            WSACleanup();
            return 1;
        }
     
        // cleanup
        closesocket(ClientSocket);
        WSACleanup();
     
        return 0;
    }
    j'ai changer le numéro de port
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    #define DEFAULT_PORT "27015"
    par 
    #define DEFAULT_PORT "27019"
    car la foncion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     // Setup the TCP listening socket
        iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
        if (iResult == SOCKET_ERROR) {
            printf("bind failed: %d\n", WSAGetLastError());
            freeaddrinfo(result);
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
    me retourne l'erreur 10048 = WSAEADDRINUSE (Address already in use. )
    le code marche dans meme pc je sent & recev bien des msg

    @Bktero
    comment appeler le programme en ligne de commande ?
    et pour la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    iResult = getaddrinfo(argv[1], DEFAULT_PORT, &hints, &result); // ligne 51
    je vois qu'elle ajoute le nom de l'exécutable comme un identificateur de Coté client au lieu d'utiliser une adresse IP ?

  5. #5
    Membre expérimenté Avatar de Vespiras
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2012
    Messages
    168
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Décembre 2012
    Messages : 168
    Par défaut
    C'est bizarre car quand tu utilises un lancement d'exécutable avec des arguments tu ne récupères pas le nom de l'exe dans argv[1] mais ton premier argument (donc ici ton nom d'hôte).

    C'est dans argv[0] que tu récupère ton nom d'exécutable.

    D'ailleurs, une petite précision :
    En C un tableau commence à l'indice 0 et fini à l'indice n+1 avec le caractère '\0'.

    Donc un tableau déclaré comme ca : int tab[3];
    peut contenir des éléments comme ceci :
    tab[0] -> un int
    tab[1] -> un int
    tab[2] -> un int
    tab[3] -> '\0' (tu ne peux pas agir dessus, c'est un marqueur de fin de tableau)

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    87
    Détails du profil
    Informations personnelles :
    Localisation : Algérie

    Informations forums :
    Inscription : Février 2010
    Messages : 87
    Par défaut
    [QUOTE=Vespiras;7561096]

    non ici le cas est différant et na rien avoir avec l'indice de tableau ,regarder bien ce que t'as écris ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    C'est dans argv[0] que tu récupère ton nom d'exécutable.
    si dans argv[0] qu'on va récupère le nom d'exécutable.donc argv[0] c'est l'indice de pointeur d'une chaine de caractères qui se termine par \n ex "nom.exe\n" , le argv[0] contient des pointeurs de chaines pas des chaines avec \n

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Donc un tableau déclaré comme ca : int tab[3]; 
    peut contenir des éléments comme ceci :
    tab[0] -> un int
    tab[1] -> un int
    tab[2] -> un int
    tab[3] -> '\0' (tu ne peux pas agir dessus, c'est un marqueur de fin de tableau)
    ici nous n'avons pas un simple tableau comme t'as penser mais on a ici un pointeur sur un tableau et on peut dire pointeur de pointeur et ou comme par exemple un tableau 2d

  7. #7
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    En C un tableau commence à l'indice 0 et fini à l'indice n+1 avec le caractère '\0'.
    Non, ceci est faux.

    Type tab[N]; n'a que N élément allant de tab[0] à tab[N-1].

    Tu confonds avec les chaînes de caractères qui, par convention, est une suite de caractère se terminant par '\0'.
    Ainsi :

    char tab[] = "foo"; déclare un tableau de 4 éléments contenant : 'f', 'o', 'o', '\0';

    Mais attention, ce '\0' n'est pas mis automatiquement à la fin de la chaîne de caractères. Le '\0' marque la fin de la chaîne de caractère, si vous écrivez dessus (ex : tab[3] = '4';), vous ne pourrez plus savoir où se termine la chaîne de caractère.

    Pour en revenir aux tableaux, il y a trois méthodes pour savoir sa taille :
    - sizeof(tab)/sizeof(tab[0]).
    /!\ uniquement possible pour les tableau (ne marche pas avec les pointeurs).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int tab[4];
    int * tab2 = tab;
    sizeof(tab2)/sizeof(tab2[0]);
    Ne marchera pas car sizeof retournera la taille de tab2, qui est un pointeurs.
    - stocker sa taille dans une variable (très utilisée pour les tableaux alloué dynamiquement) ;
    - utiliser une valeur "invalide" à la fin de son tableau. Cette valeur peut être NULL, 0, '\0', -1, ...
    L'important c'est de prendre une valeur possible (ex : 0 pour un unsigned int) qu'on considérera comme invalide (ex : on ne veut stocker que des nombres strictement positifs dans le tableau), c'est à dire qu'on est sûr de ne pas retrouver dans les autres éléments du tableau.

Discussions similaires

  1. REQ : Algo pour vérification saisie du "Numero TVA"
    Par Eric.H dans le forum Langage
    Réponses: 4
    Dernier message: 28/01/2009, 10h23
  2. [FTP] besoin d'aide pour source code
    Par planete-venus dans le forum Langage
    Réponses: 1
    Dernier message: 02/06/2007, 15h01
  3. Question pour le code d'un jeux
    Par saebakun dans le forum Flash
    Réponses: 7
    Dernier message: 17/03/2007, 13h45
  4. Code VBA pour calcul compte client > ou < à 100- Urgent
    Par mabeatrice@yahoo.fr dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 13/03/2007, 16h39

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