/**
*
*  @File : exo_02c.cxx
*
*  @Authors : D. Mathieu
*             M. Laporte
*
*  @Date : 19/12/2000
*
*  @Version : V1.0
*
*  @Synopsis :
*
**/
#include <iostream>
#include <string>
#include <exception>
#include <cstdlib>        // atoi()
#include <climits>        // MAX_INPUT

#include <sys/types.h>    // size_t, fd_set
#include <sys/socket.h>   // MSG_OOB
#include <netinet/in.h>   // htons()

#include "CExc.h"
#include "CExcFctSyst.h"
#include "nsSysteme.h"
#include "nsNet.h"

using namespace nsSysteme;
using namespace nsNet;

int std::ppal (int argc, char * argv []) throw (exception)
{
    if (3 != argc)
        throw nsBAO::CExc (string ("Usage : ") + argv [0] +
                           " <Machine> <Port>");

    const int sd = ClientSockInStream (AddrIP (argv [1]),
                                       ::htons (::atoi (argv [2])));

    char Tampon [MAX_INPUT];

    fd_set MaskRead, MaskExc;

    FD_ZERO (&MaskRead);
    FD_ZERO (&MaskExc);
    FD_SET (sd, &MaskRead);
    FD_SET (sd, &MaskExc);

    // On pourrait n'initialiser qu'un seul masque et l'affecter à l'autre si on
    //   était sûr que l'affectation est défnie pour le type fd_set

    for (; ;)
    {
        Select (sd + 1, &MaskRead, 0, &MaskExc);

        // Pour traiter tous les messages urgents avant les messages normaux,
        //   un seul message est traité par boucle ==> s'il y a un message
        //   urgent en attente (arrivé après exécution de Recv()), c'est lui
        //   qui est lu

        if (FD_ISSET (sd, &MaskExc))
        {
            Recv (sd, Tampon, 1, MSG_OOB);
            cout << "Msg urgent : " << Tampon [0] << endl;
            FD_SET (sd, &MaskRead);
        }
        else
        {
            size_t Lg = Recv (sd, Tampon, MAX_INPUT - 1);
            Tampon [Lg] = '\0';

            // Test si le serveur est déconnecté

            if (0 == Lg) break;

            cout << "Msg normal : " << Tampon << endl;
            FD_SET (sd, &MaskExc);
        }
    }
    return 0;

} // ppal()