Programmation Réseau

BSD Sockets

Voici un exemple de programmation des sockets sous win32 en émulation BSD (le code : il contient le client et le serveur plus un serveur en thread). Je rajouterais un exemple bi-directionnel (le client recevant des données du serveur) plus tard. Le code décrit ci-dessous fonctionne sous n'importe quel OS supportant les sockets BSD...

La partie Client :

void main(int argc, char **argv)
{
    int s = NULL;

    struct sockaddr_in sock;
    struct hostent *hptr;
    char data[80] = "\0";

    if((s = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        perror("socket");
        exit(0);
    }

    memset (&sock, 0, sizeof(sock));
    sock.sin_family = AF_INET;
    sock.sin_port = atoi(argv[2]);

    if((hptr = gethostbyname(argv[1])) == NULL)
    {
        perror("gethostbyname");
        exit(0);
    }

    memcpy (&sock.sin_addr.s_addr, hptr->h_addr, hptr->h_length);

    fprintf(stdout, "Connexion a %s:%s...\n", argv[1], argv[2]);

    if(connect (s, (struct sockaddr *)&sock, sizeof(sock)) == SOCKET_ERROR)
    {
        perror("connect");
        exit(0);
    }

    if(send (s, argv[3], strlen(argv[3]), 0) == SOCKET_ERROR)
    {
        perror("write");
        exit(0);
    }

    closesocket(s);
}

La partie Serveur :

void main(int argc, char **argv)
{
    int s = NULL, addrlen;

    struct sockaddr_in sock;
    struct sockaddr_in *ptr = NULL;
    struct sockaddr addr;
    struct hostent *hp = NULL;
    char hostname[64];

    if(gethostname(hostname, 64) == SOCKET_ERROR)
    {
        perror("bind");
        exit(0);
    }

    if((s = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
    {
        perror("socket");
        exit(0);
    }

    sock.sin_family = AF_INET;
    sock.sin_port = atoi(argv[1]);
    sock.sin_addr.s_addr = INADDR_ANY;

    if(bind (s, (struct sockaddr *)&sock, sizeof(sock)) == SOCKET_ERROR)
    {
        perror("bind");
        exit(0);
    }

    fprintf(stdout, "Serveur %s:%d\n", hostname, sock.sin_port);

    addrlen = sizeof(addr);

    if(getsockname (s, &addr, &addrlen) == SOCKET_ERROR)
    {
        werror("getsockname");
        exit(0);
    }

    ptr = (struct sockaddr_in *)&addr;

    if(listen (s, 5) == SOCKET_ERROR)
    {
        perror("listen");
        exit(0);
    }

    while(1)
    {
        int sa = NULL, nbytes = 0;
        char buf[80];

        if((sa = accept(s, 0, 0)) == INVALID_SOCKET)
        {
            perror("getsockname");
            exit(0);
        }

        getpeername(sa, &addr, &addrlen);

        hp = gethostbyaddr ((char *)&ptr->sin_addr, 4, AF_INET);

        fprintf(stdout, "Connexion depuis %s(%s):%d\n", hp->h_name, inet_ntoa(ptr->sin_addr), ptr->sin_port);
        fprintf(stdout, "Data :\n\t");

        do
        {
            memset(buf, 0, sizeof(buf));
            nbytes = recv (sa, buf, sizeof(buf), 0);

            fprintf(stdout, "%s", buf);
        } while(nbytes != SOCKET_ERROR && nbytes != 0);

        if(nbytes == SOCKET_ERROR)
        {
            perror("recv");
        }

        fprintf(stdout, "\nData Fin.\n");

        close (sa);
    }
}