begin process at 2012 05 29 00:47:48
  Trouver un code source :
 
dans
 
Accueil > Forum > 

Archive C/C++

 > 

Archives

 > 

OpenGL

 > 

Comment Gerer des sockets non bloquant sous OpenGl


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Comment Gerer des sockets non bloquant sous OpenGl

dimanche 20 juillet 2003 à 17:34:01 | Comment Gerer des sockets non bloquant sous OpenGl

kawito

Bonjour,

je devellope un jeu (2d + scene 3d) en Opengl et C++, je desire utiliser seulement opengl et c++ (console app), pour des raisons de portabilitée,donc pas de MFC !
et biensur j'aimerais que ce jeu ce joue en reseau :

j'ai donc fais un client serveur tcp (winsock version 1.1)
mais les fonction accept et recv sont bloquante ,

mon serveur passe en ecoute ,puis je fais un accept sur le socket client (1er client)
la fonction accept et bloquante !
j'ai donc cherché comment faire pour eviter ce probleme, et la je bloque un peu ?
j'ai bien vu des truc comme SWAAsyncSelect(socket,hWnd,wMsg,Event);

comment reccuperer les messages de windows wMsg sous opengl et l'identificateur de la fenetre ?
pour que je puisse utiliser les fonctions du type WSA


je voudrais que le serveur detecte une nouvelle connexion cliente :
une fois mon serveur en ecoute je voudrais qu'il scrute les evenements network, pour faire selon un accept un send ou un recv.
le serveur possede une liste dynamique de socket client

si evenement network FD_ACCEPT
creer cellule socket cliente
faire un accet sur ce socket
connexion acceptée ?

scruter les evenements j'usqu'au prochain accept et on recommence, creation de la cellule socket cliente et accept...

ainsi je pense que meme si la fonction accept et bloquante
vu que je detecte une demande de connexion avant de lancer la fonction accept, cela devrais fonctionner ?

ou peut etre faut il utiliser les threads ,mais la j'ai pas tous compris !
comment utiliser un thread sous opengl sans MFC

AUTRE SOUCIS :

j'utilise winsock 1.1 car losrque j'inclus winsock2.h
avec la lib ws2_32.lib
j'ai des erreurs sur fd_set redefined etc......
impossible d'utiliser winsock version 2 !

ya t'il un probleme dans windows.h, il me semble que winsock.h est systematiquement implementé ,ou quil manque des directives dans winsock2.h ?

AUTRE QUESTION:

quel est l'architecture d'un programme complex en opengl sans MFC,ou placer les traitements du programme ?
comme la getion des sockets reseau

glutReshapeFunc(rafraichir);
glutIdleFunc(callBackFonction);
glutDisplayFunc(afficher);
glutMouseFunc(souris);
glutKeyboardFunc(clavier);


merci a vous de me donner un coup de main

dimanche 20 juillet 2003 à 19:34:19 | Re : Comment Gerer des sockets non bloquant sous OpenGl

aardman

Membre Club
Salut,

1) WSA=> windows socket api => winsock 2
Donc je pense pas que tu puisse utiliser les fonctions WSA en socket 1.1.

2) Ensuite, la fonction WSAAsyncSelect transcrit les evenement reseau en messages windows, donc il te faut une fenetre (meme invisible) pour recevoir et traiter les messages.
Pour detecter et accepter une nouvelle connection, tu traite FD_ACCEPT. Dans ce message, ou plutot cette notification de message, tu met tout tes trucs: tu crée tes cellules, tu accepte la connection... Si accept retourne autre chose que INVALID_SOCKET, c'est que la connection a reussi.

3) Enfin, pour les erreurs de definition,
- soit tu inclus winsock2.h avant windows.h (ca c si tu as juste des probs de redefinition avec winsock2.h)
- soit tu met tout en haut, avant tout les header:
#define _WIN32_WINNT 0x0500
(c'est le mieux)

4) J'y connais rien en OPENGL, désolé.


-------------------------------
Réponse au message :
-------------------------------

> Bonjour,
>
> je devellope un jeu (2d + scene 3d) en Opengl et C++, je desire utiliser seulement opengl et c++ (console app), pour des raisons de portabilitée,donc pas de MFC !
> et biensur j'aimerais que ce jeu ce joue en reseau :
>
> j'ai donc fais un client serveur tcp (winsock version 1.1)
> mais les fonction accept et recv sont bloquante ,
>
> mon serveur passe en ecoute ,puis je fais un accept sur le socket client (1er client)
> la fonction accept et bloquante !
> j'ai donc cherché comment faire pour eviter ce probleme, et la je bloque un peu ?
> j'ai bien vu des truc comme SWAAsyncSelect(socket,hWnd,wMsg,Event);
>
> comment reccuperer les messages de windows wMsg sous opengl et l'identificateur de la fenetre ?
> pour que je puisse utiliser les fonctions du type WSA
>
>
> je voudrais que le serveur detecte une nouvelle connexion cliente :
> une fois mon serveur en ecoute je voudrais qu'il scrute les evenements network, pour faire selon un accept un send ou un recv.
> le serveur possede une liste dynamique de socket client
>
> si evenement network FD_ACCEPT
> creer cellule socket cliente
> faire un accet sur ce socket
> connexion acceptée ?
>
> scruter les evenements j'usqu'au prochain accept et on recommence, creation de la cellule socket cliente et accept...
>
> ainsi je pense que meme si la fonction accept et bloquante
> vu que je detecte une demande de connexion avant de lancer la fonction accept, cela devrais fonctionner ?
>
> ou peut etre faut il utiliser les threads ,mais la j'ai pas tous compris !
> comment utiliser un thread sous opengl sans MFC
>
> AUTRE SOUCIS :
>
> j'utilise winsock 1.1 car losrque j'inclus winsock2.h
> avec la lib ws2_32.lib
> j'ai des erreurs sur fd_set redefined etc......
> impossible d'utiliser winsock version 2 !
>
> ya t'il un probleme dans windows.h, il me semble que winsock.h est systematiquement implementé ,ou quil manque des directives dans winsock2.h ?
>
> AUTRE QUESTION:
>
> quel est l'architecture d'un programme complex en opengl sans MFC,ou placer les traitements du programme ?
> comme la getion des sockets reseau
>
> glutReshapeFunc(rafraichir);
> glutIdleFunc(callBackFonction);
> glutDisplayFunc(afficher);
> glutMouseFunc(souris);
> glutKeyboardFunc(clavier);
>
>
> merci a vous de me donner un coup de main
>
>
lundi 21 juillet 2003 à 11:16:54 | Re : Comment Gerer des sockets non bloquant sous OpenGl

Manson

salut,

moi je dirais que tu initialise la dll donc avec un WSAStartup,
ensuite tu initialiase la socket du "server", tu cree un nouveau thread dans lequel tu fais tourner un select (c'est mieux, 'fin je trouve) et enfin en fonction des FD tu transcrit le msg.

Bon courage.

Arno



-------------------------------
Réponse au message :
-------------------------------

> Salut,
>
> 1) WSA=> windows socket api => winsock 2
> Donc je pense pas que tu puisse utiliser les fonctions WSA en socket 1.1.
>
> 2) Ensuite, la fonction WSAAsyncSelect transcrit les evenement reseau en messages windows, donc il te faut une fenetre (meme invisible) pour recevoir et traiter les messages.
> Pour detecter et accepter une nouvelle connection, tu traite FD_ACCEPT. Dans ce message, ou plutot cette notification de message, tu met tout tes trucs: tu crée tes cellules, tu accepte la connection... Si accept retourne autre chose que INVALID_SOCKET, c'est que la connection a reussi.
>
> 3) Enfin, pour les erreurs de definition,
> - soit tu inclus winsock2.h avant windows.h (ca c si tu as juste des probs de redefinition avec winsock2.h)
> - soit tu met tout en haut, avant tout les header:
> #define _WIN32_WINNT 0x0500
> (c'est le mieux)
>
> 4) J'y connais rien en OPENGL, désolé.
>
>
> -------------------------------
> Réponse au message :
> -------------------------------
>
> > Bonjour,
> >
> > je devellope un jeu (2d + scene 3d) en Opengl et C++, je desire utiliser seulement opengl et c++ (console app), pour des raisons de portabilitée,donc pas de MFC !
> > et biensur j'aimerais que ce jeu ce joue en reseau :
> >
> > j'ai donc fais un client serveur tcp (winsock version 1.1)
> > mais les fonction accept et recv sont bloquante ,
> >
> > mon serveur passe en ecoute ,puis je fais un accept sur le socket client (1er client)
> > la fonction accept et bloquante !
> > j'ai donc cherché comment faire pour eviter ce probleme, et la je bloque un peu ?
> > j'ai bien vu des truc comme SWAAsyncSelect(socket,hWnd,wMsg,Event);
> >
> > comment reccuperer les messages de windows wMsg sous opengl et l'identificateur de la fenetre ?
> > pour que je puisse utiliser les fonctions du type WSA
> >
> >
> > je voudrais que le serveur detecte une nouvelle connexion cliente :
> > une fois mon serveur en ecoute je voudrais qu'il scrute les evenements network, pour faire selon un accept un send ou un recv.
> > le serveur possede une liste dynamique de socket client
> >
> > si evenement network FD_ACCEPT
> > creer cellule socket cliente
> > faire un accet sur ce socket
> > connexion acceptée ?
> >
> > scruter les evenements j'usqu'au prochain accept et on recommence, creation de la cellule socket cliente et accept...
> >
> > ainsi je pense que meme si la fonction accept et bloquante
> > vu que je detecte une demande de connexion avant de lancer la fonction accept, cela devrais fonctionner ?
> >
> > ou peut etre faut il utiliser les threads ,mais la j'ai pas tous compris !
> > comment utiliser un thread sous opengl sans MFC
> >
> > AUTRE SOUCIS :
> >
> > j'utilise winsock 1.1 car losrque j'inclus winsock2.h
> > avec la lib ws2_32.lib
> > j'ai des erreurs sur fd_set redefined etc......
> > impossible d'utiliser winsock version 2 !
> >
> > ya t'il un probleme dans windows.h, il me semble que winsock.h est systematiquement implementé ,ou quil manque des directives dans winsock2.h ?
> >
> > AUTRE QUESTION:
> >
> > quel est l'architecture d'un programme complex en opengl sans MFC,ou placer les traitements du programme ?
> > comme la getion des sockets reseau
> >
> > glutReshapeFunc(rafraichir);
> > glutIdleFunc(callBackFonction);
> > glutDisplayFunc(afficher);
> > glutMouseFunc(souris);
> > glutKeyboardFunc(clavier);
> >
> >
> > merci a vous de me donner un coup de main
> >
> >
>
lundi 21 juillet 2003 à 21:26:15 | Re : Comment Gerer des sockets non bloquant sous OpenGl

kawito

Salut,

voici ce que j'ai fais :

j'ai cree une class socket (socketReseau)
une class serveur qui derive de socketReseau
une class client qui derive de socketReseau egalement

la class serveur possede une liste dynamique de type generic ici la liste est du type socketReseau, cette liste correspond aux clients qui se connecterons.
le type Liste est une liste generic ,on peut y acceder avec un iterateur ou comme un tableau Liste[0].

pour ce qui est des buffers d'entre sortie des sockets (voir class socketReseau, j'ai prevu 2 buffers un pour l'entree et un pour la sortie.

je ne sais pas encore ce qui est le mieux au niveau des buffers ,ais je fais le bon choix ?
peut etre q'un seul buffer suffirais ,et pourrais etre sur un void* !!?
chaque buffer a une taille de 1024 (voir constante)

voici ce que fais mon serveur:

initialiser winsock
demarrer serveur
ecouter

accept (bloque !, il attend une connexion d'un client, donc pas cool !)

si client accepte,

le serveur attend le nom du client
recv (bloque aussi !)

le serveur envoie son nom au client
send

voici ce que fais mon client:

initialiser winsock

connecter

le client envoie son nom au serveur
send

le client attend le nom du serveur
recv (bloque !)



je vous passe les detaille de la saisie au clavier du port de l'adresse ip du serveur, du nom du client et du nom du serveur !

BREF :
mon client se connecte correctement a mon serveur
ils echangent leurs nom ,et je fais afficher l'adresse ip de chacun a l'ecran

pour l'instant le serveur ne gere q'un seul client (voir constructeur de la class serveur.(la liste n'a q'un socket)

l idée du thread, j'y ais bien pensais ,mais j'ai pas tout compris comment faire,declarer un thread et comment l'implenter dans mon programme...

vu mon architecture quel est la meilleur methode, et ne pas oublier que j'utilise GLUT et c++ en console application



voici mon MAIN :
int main(int argc, char** argv)
{
int idFenetre; // Identifiant de la fenêtre principale
/*** Initialisations ***/
glutInit(&argc, argv); // Initialise la bibliothèque GLUT
initialiserFenetre(&idFenetre);
initialiserOpenGL();
initialiserVariables();
/*** Boucle principale ***/
glutReshapeFunc(rafraichir);
glutIdleFunc(callBackFonction);
glutDisplayFunc(afficher);
glutMouseFunc(souris);
glutKeyboardFunc(clavier);
glutMainLoop();
return 0;
}

et mes headers socket,serveur,client....

/************ socket.h ****************/

#ifndef __SOCKET__
#define __SOCKET__

#include <iostream.h>
#define TAILLE_BUFFER_SOCKET 1024
#define PORT_PAR_DEFAUT 5500
#define TYPE_SOCKET_PAR_DEFAUT SOCK_STREAM
#define FAMILLE_SOCKET_PAR_DEFAUT AF_INET
#define BLOQUER_RECEPTION 0
#define BLOQUER_EMISSION 1
#define BLOQUER_RECEPTION_EMISSION 2

/**************************/
/* MA CLASSE SOCKET
/**************************/


class socketReseau
{
private :

SOCKADDR_IN socketAdresseIn;
int socketType;
int socketProtocol;
SOCKET socketConnexion;
char* bufferEntree;
char* bufferSortie;

public:

socketReseau()
{
memset(&socketAdresseIn, 0, sizeof(socketAdresseIn));
socketAdresseIn.sin_family = FAMILLE_SOCKET_PAR_DEFAUT;
socketAdresseIn.sin_port = htons(PORT_PAR_DEFAUT);
//socketAdresseIn.sin_addr.s_addr = INADDR_ANY;
socketType = TYPE_SOCKET_PAR_DEFAUT;
bufferEntree = new char [TAILLE_BUFFER_SOCKET];
bufferEntree[0] = '\0';
bufferSortie = new char [TAILLE_BUFFER_SOCKET];
bufferSortie[0] = '\0';
socketConnexion = INVALID_SOCKET;
evenementReseau = NULL;
}

~socketReseau()
{
int erreur = 0;

erreur = closesocket(socketConnexion);
if (erreur == SOCKET_ERROR)
{
cerr << "Erreur a la fermeture du socketReseau" << WSAGetLastError() << endl;
}
else
{
cout << "fermeture socketReseau reussi" << endl;
}

cout << "Destructeur Socket " << endl;
}

SOCKADDR_IN* lireSocketAdresseInRef(void) { return(&socketAdresseIn); }
SOCKADDR_IN lireSocketAdresseIn(void) { return(socketAdresseIn); }
char* lireAdresseSocketAdresseIn(void) { return(inet_ntoa(socketAdresseIn.sin_addr)); }
int lireSocketType(void) { return(socketType); }
int lireSocketProtocol(void) { return(socketProtocol); }
int lireFamilleSocketAdresseIn(void) { return(socketAdresseIn.sin_family); }
unsigned short lirePortSocketAdresseIn(void) { return(socketAdresseIn.sin_port); }
SOCKET lireSocketConnexion(void) { return(socketConnexion); }
SOCKET* lireSocketConnexionRef(void) { return(&socketConnexion); }
char* lireBufferEntree(void) { return(bufferEntree); }
char* lireBufferSortie(void) { return(bufferSortie); }
void ecrireAdresseSocketAdresseIn(char* a);
void ecrireAdresseSocketAdresseInLocal(void);
void ecrireSocketType(int t) { socketType = t; }
void ecrireSocketProtocol(int p) { socketProtocol = p; }
void ecrireSocketConnexion(SOCKET s) { socketConnexion = s; }
void ecrireFamilleSocketAdresseIn(int f) { socketAdresseIn.sin_family = f; }
void ecrirePortSocketAdresseIn(unsigned short& p) { socketAdresseIn.sin_port = htons(p); }
void ecrireBufferEntree(char* chE) { bufferEntree = chE; }
void ecrireBufferSortie(char* chS) { bufferSortie = chS; }
int bindSocket(void);
int creerSocket(void);
int envoyer(void);
int recevoir(void);
void fermerSocket(void);
int bloquerSocket(void);
};


/*** Initialiser la version de Winsock et demarre Winsock ***/
int initialiserWinsock(void);


#endif
/************ socket.h ****************/


/**************************/
/* MA CLASSE SERVEUR
/**************************/

le type Liste est une liste dynamique sur un type quelconque
elle derive de socketReseau

/************ serveur.h ****************/
#ifndef __SERVEUR__
#define __SERVEUR__

#include "listeGenerique.h" // Listes génériques
#include "listeTemplate.h" // Listes templates
#include "socket.h"

#define SERVEUR_PRET true
#define SERVEUR_INDISPONIBLE false

class serveur : public socketReseau
{
private :

bool status;
int connexionMax;
Liste<socketReseau> listeSocketsClients;

public:

serveur()
{
status = false;
connexionMax = 5;
listeSocketsClients.creerListe(socketReseau(), 1); // ici je cree une cellule socketReseau destine a recevoir le client
}
~serveur();
void creerListeSocketsClients(int nbC)
{
listeSocketsClients.creerListe(socketReseau(), nbC);
}
bool lireStatus(void) { return(status); }
void ecrireStatus(bool s) { status = s; }
char* AdresseIpDuClient(int numC);
int envoyerClient(int numC, char* chOut);
char* recevoirClient(int numC);
int envoyerClients(char* chOutAll);
int recevoirClients(char* chInAll);
int demarrerServeur(unsigned short & port, int socType, int socFam);
int ecouter(void);
int attenteConnexionsClients(void);
void arreterServeur(void);
};

#endif
/************ serveur.h ****************/


/**************************/
/* MA CLASSE CLIENT
/**************************/


#ifndef __CLIENT__
#define __CLIENT__

#include "socket.h"

class client : public socketReseau
{
private :

char* adresseIPServeur;

public:
client(void) { }
~client(void) { }

char* lireAdresseIPServeur() { return(adresseIPServeur); }
void ecrireAdresseIPServeur(char* ch) { adresseIPServeur = ch;}

int connexionServeur(char* adresseIPServeur, unsigned short & port, int socType, int socFam);
int Connecter();
void arreterClient();
};


#endif
/************ serveur.h ****************/



voici un aperçu du serveur.cpp


/*** Destructeur ***/
serveur::~serveur()
{
int k = 0;
int erreur = 0;

erreur = closesocket(listeSocketsClients[k].lireSocketConnexion());
if (erreur == SOCKET_ERROR)
{
cerr << "Erreur Fermeture Socket Client pendant l'arret du serveur :" << WSAGetLastError() << endl;
}
WSACleanup(); // arret de winsock
listeSocketsClients.detruireListe();
}

int serveur::demarrerServeur(unsigned short & port, int socType, int socFam)
{
int erreur = 0;
this -> ecrireFamilleSocketAdresseIn(socFam);
this -> ecrireSocketType(socType);
this -> ecrireAdresseSocketAdresseInLocal();
this -> ecrirePortSocketAdresseIn(port);
this -> creerSocket();
this -> bindSocket();
if (this -> lireSocketConnexion() != INVALID_SOCKET)
{
cout << "SOCKET SERVEUR CREE AVEC SUCCES" << endl;
cout << "ADRESSE : " << lireAdresseSocketAdresseIn() << endl;
cout << "PORT : " << lireSocketAdresseIn().sin_port << endl;
return(0);
}
else
{
cerr << "ERREUR LORS DE LA CREATION DU SOCKET SERVEUR" << endl;
erreur = closesocket(this -> lireSocketConnexion());
if (erreur == SOCKET_ERROR)
{
cerr << "Erreur fermeture socket serveur lors du demarrage suite a une erreur a la creation : " << WSAGetLastError() << endl;
WSACleanup(); // arret de winsock
return(INVALID_SOCKET);
}

return(INVALID_SOCKET);
}
return(0);
}




/*** Mise en ecoute du serveur ***/
int serveur::ecouter(void)
{
if (listen(this -> lireSocketConnexion(), 0) == 0)
{
cout << "PASSAGE EN ECOUTE DU SERVEUR REUSSI" << endl;
return(0);
}
else
{
cerr << "ERREUR LORS DU PASSAGE EN ECOUTE DU SERVEUR : " << WSAGetLastError() << endl;
}
return(SOCKET_ERROR);
}

/*** Attendre la connexion du client ***/
int serveur::attenteConnexionsClients(void)
{
int tailleAdresse = 0;

tailleAdresse = sizeof(struct sockaddr_in);
listeSocketsClients[0].ecrireSocketConnexion(accept(this -> lireSocketConnexion(), (SOCKADDR*)listeSocketsClients[0].lireSocketAdresseInRef() ,&tailleAdresse));
if (listeSocketsClients[0].lireSocketConnexion() != INVALID_SOCKET)
{
cout << "CONNECTION CLIENT ACCEPTEE" << endl;
cout << "ADRESSE DU CLIENT : [" << listeSocketsClients[0].lireAdresseSocketAdresseIn() << "]" << endl;
return(0);
}
else
{
cerr << "ERREUR LORS DU L'ACCEPTATION DU CLIENT : %d\n" << WSAGetLastError() << endl;
return(SOCKET_ERROR);
}
return(0);
}

-------------------------------
Réponse au message :
-------------------------------

> salut,
>
> moi je dirais que tu initialise la dll donc avec un WSAStartup,
> ensuite tu initialiase la socket du "server", tu cree un nouveau thread dans lequel tu fais tourner un select (c'est mieux, 'fin je trouve) et enfin en fonction des FD tu transcrit le msg.
>
> Bon courage.
>
> Arno
>
>
>
> -------------------------------
> Réponse au message :
> -------------------------------
>
> > Salut,
> >
> > 1) WSA=> windows socket api => winsock 2
> > Donc je pense pas que tu puisse utiliser les fonctions WSA en socket 1.1.
> >
> > 2) Ensuite, la fonction WSAAsyncSelect transcrit les evenement reseau en messages windows, donc il te faut une fenetre (meme invisible) pour recevoir et traiter les messages.
> > Pour detecter et accepter une nouvelle connection, tu traite FD_ACCEPT. Dans ce message, ou plutot cette notification de message, tu met tout tes trucs: tu crée tes cellules, tu accepte la connection... Si accept retourne autre chose que INVALID_SOCKET, c'est que la connection a reussi.
> >
> > 3) Enfin, pour les erreurs de definition,
> > - soit tu inclus winsock2.h avant windows.h (ca c si tu as juste des probs de redefinition avec winsock2.h)
> > - soit tu met tout en haut, avant tout les header:
> > #define _WIN32_WINNT 0x0500
> > (c'est le mieux)
> >
> > 4) J'y connais rien en OPENGL, désolé.
> >
> >
> > -------------------------------
> > Réponse au message :
> > -------------------------------
> >
> > > Bonjour,
> > >
> > > je devellope un jeu (2d + scene 3d) en Opengl et C++, je desire utiliser seulement opengl et c++ (console app), pour des raisons de portabilitée,donc pas de MFC !
> > > et biensur j'aimerais que ce jeu ce joue en reseau :
> > >
> > > j'ai donc fais un client serveur tcp (winsock version 1.1)
> > > mais les fonction accept et recv sont bloquante ,
> > >
> > > mon serveur passe en ecoute ,puis je fais un accept sur le socket client (1er client)
> > > la fonction accept et bloquante !
> > > j'ai donc cherché comment faire pour eviter ce probleme, et la je bloque un peu ?
> > > j'ai bien vu des truc comme SWAAsyncSelect(socket,hWnd,wMsg,Event);
> > >
> > > comment reccuperer les messages de windows wMsg sous opengl et l'identificateur de la fenetre ?
> > > pour que je puisse utiliser les fonctions du type WSA
> > >
> > >
> > > je voudrais que le serveur detecte une nouvelle connexion cliente :
> > > une fois mon serveur en ecoute je voudrais qu'il scrute les evenements network, pour faire selon un accept un send ou un recv.
> > > le serveur possede une liste dynamique de socket client
> > >
> > > si evenement network FD_ACCEPT
> > > creer cellule socket cliente
> > > faire un accet sur ce socket
> > > connexion acceptée ?
> > >
> > > scruter les evenements j'usqu'au prochain accept et on recommence, creation de la cellule socket cliente et accept...
> > >
> > > ainsi je pense que meme si la fonction accept et bloquante
> > > vu que je detecte une demande de connexion avant de lancer la fonction accept, cela devrais fonctionner ?
> > >
> > > ou peut etre faut il utiliser les threads ,mais la j'ai pas tous compris !
> > > comment utiliser un thread sous opengl sans MFC
> > >
> > > AUTRE SOUCIS :
> > >
> > > j'utilise winsock 1.1 car losrque j'inclus winsock2.h
> > > avec la lib ws2_32.lib
> > > j'ai des erreurs sur fd_set redefined etc......
> > > impossible d'utiliser winsock version 2 !
> > >
> > > ya t'il un probleme dans windows.h, il me semble que winsock.h est systematiquement implementé ,ou quil manque des directives dans winsock2.h ?
> > >
> > > AUTRE QUESTION:
> > >
> > > quel est l'architecture d'un programme complex en opengl sans MFC,ou placer les traitements du programme ?
> > > comme la getion des sockets reseau
> > >
> > > glutReshapeFunc(rafraichir);
> > > glutIdleFunc(callBackFonction);
> > > glutDisplayFunc(afficher);
> > > glutMouseFunc(souris);
> > > glutKeyboardFunc(clavier);
> > >
> > >
> > > merci a vous de me donner un coup de main
> > >
> > >
> >
>
samedi 16 août 2003 à 13:41:22 | Re : Comment Gerer des sockets non bloquant sous OpenGl

cbestern

en quelques mots pour les thrad:
définir 2 handle, 1 pour le thread et un pour l'évenement
(un évenement est soit signer soit non signer comme un bolleen)
HANDLE HandTread=NULL;
HANDLE HandEvent=NULL;

//définit ta fonction thread (qui se nome ici FonctionThread)
DWORD FonctionThread(LPVOID)
{
//ici il boucle juqu'a l'arriver de l'évement

while(WaitForSingleObject(HandEventEm,0)!=WAIT_OBJECT_0)
{
//fait Ce que tu veut!!!
}
}

//pour le lancer
void StartThread()
{
assert(!HandTread);
assert(!HandEvent);

HandEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
DWORD ThreadIDRe;
//c ici même qu'il crée le thread
HandTread = CreateThread(NULL,0,FonctionThread,NULL,0,&ThreadIDRe);
}


//et pour l'arrêter:
void Stopthread()
{
assert(HandTread);
assert(HandEvent);
//signale l'évenement pour le faire sortir de sa boucle
SetEvent(HandEvent);
WaitForSingleObject(HandEvent,INFINITE);
CloseHandle(HandTread);
CloseHandle(HandEvent);
HandTread = NULL;
HandEvente = NULL;
}


Bon ça c pour une utilisation normale, juste un petit truc, il ne faut pas que ton programme finisse avant ton thread.

j'espere avoir été assez clair.
Sinon regarde les exemples de client serveurs, ça pourrais t'aider
-------------------------------
Réponse au message :
-------------------------------

> Salut,
>
> voici ce que j'ai fais :
>
> j'ai cree une class socket (socketReseau)
> une class serveur qui derive de socketReseau
> une class client qui derive de socketReseau egalement
>
> la class serveur possede une liste dynamique de type generic ici la liste est du type socketReseau, cette liste correspond aux clients qui se connecterons.
> le type Liste est une liste generic ,on peut y acceder avec un iterateur ou comme un tableau Liste[0].
>
> pour ce qui est des buffers d'entre sortie des sockets (voir class socketReseau, j'ai prevu 2 buffers un pour l'entree et un pour la sortie.
>
> je ne sais pas encore ce qui est le mieux au niveau des buffers ,ais je fais le bon choix ?
> peut etre q'un seul buffer suffirais ,et pourrais etre sur un void* !!?
> chaque buffer a une taille de 1024 (voir constante)
>
> voici ce que fais mon serveur:
>
> initialiser winsock
> demarrer serveur
> ecouter
>
> accept (bloque !, il attend une connexion d'un client, donc pas cool !)
>
> si client accepte,
>
> le serveur attend le nom du client
> recv (bloque aussi !)
>
> le serveur envoie son nom au client
> send
>
> voici ce que fais mon client:
>
> initialiser winsock
>
> connecter
>
> le client envoie son nom au serveur
> send
>
> le client attend le nom du serveur
> recv (bloque !)
>
>
>
> je vous passe les detaille de la saisie au clavier du port de l'adresse ip du serveur, du nom du client et du nom du serveur !
>
> BREF :
> mon client se connecte correctement a mon serveur
> ils echangent leurs nom ,et je fais afficher l'adresse ip de chacun a l'ecran
>
> pour l'instant le serveur ne gere q'un seul client (voir constructeur de la class serveur.(la liste n'a q'un socket)
>
> l idée du thread, j'y ais bien pensais ,mais j'ai pas tout compris comment faire,declarer un thread et comment l'implenter dans mon programme...
>
> vu mon architecture quel est la meilleur methode, et ne pas oublier que j'utilise GLUT et c++ en console application
>
>
>
> voici mon MAIN :
> int main(int argc, char** argv)
> {
> int idFenetre; // Identifiant de la fenêtre principale
> /*** Initialisations ***/
> glutInit(&argc, argv); // Initialise la bibliothèque GLUT
> initialiserFenetre(&idFenetre);
> initialiserOpenGL();
> initialiserVariables();
> /*** Boucle principale ***/
> glutReshapeFunc(rafraichir);
> glutIdleFunc(callBackFonction);
> glutDisplayFunc(afficher);
> glutMouseFunc(souris);
> glutKeyboardFunc(clavier);
> glutMainLoop();
> return 0;
> }
>
> et mes headers socket,serveur,client....
>
> /************ socket.h ****************/
>
> #ifndef __SOCKET__
> #define __SOCKET__
>
> #include <iostream.h>
> #define TAILLE_BUFFER_SOCKET 1024
> #define PORT_PAR_DEFAUT 5500
> #define TYPE_SOCKET_PAR_DEFAUT SOCK_STREAM
> #define FAMILLE_SOCKET_PAR_DEFAUT AF_INET
> #define BLOQUER_RECEPTION 0
> #define BLOQUER_EMISSION 1
> #define BLOQUER_RECEPTION_EMISSION 2
>
> /**************************/
> /* MA CLASSE SOCKET
> /**************************/

>
> class socketReseau
> {
> private :
>
> SOCKADDR_IN socketAdresseIn;
> int socketType;
> int socketProtocol;
> SOCKET socketConnexion;
> char* bufferEntree;
> char* bufferSortie;
>
> public:
>
> socketReseau()
> {
> memset(&socketAdresseIn, 0, sizeof(socketAdresseIn));
> socketAdresseIn.sin_family = FAMILLE_SOCKET_PAR_DEFAUT;
> socketAdresseIn.sin_port = htons(PORT_PAR_DEFAUT);
> //socketAdresseIn.sin_addr.s_addr = INADDR_ANY;
> socketType = TYPE_SOCKET_PAR_DEFAUT;
> bufferEntree = new char [TAILLE_BUFFER_SOCKET];
> bufferEntree[0] = '\0';
> bufferSortie = new char [TAILLE_BUFFER_SOCKET];
> bufferSortie[0] = '\0';
> socketConnexion = INVALID_SOCKET;
> evenementReseau = NULL;
> }
>
> ~socketReseau()
> {
> int erreur = 0;
>
> erreur = closesocket(socketConnexion);
> if (erreur == SOCKET_ERROR)
> {
> cerr << "Erreur a la fermeture du socketReseau" << WSAGetLastError() << endl;
> }
> else
> {
> cout << "fermeture socketReseau reussi" << endl;
> }
>
> cout << "Destructeur Socket " << endl;
> }
>
> SOCKADDR_IN* lireSocketAdresseInRef(void) { return(&socketAdresseIn); }
> SOCKADDR_IN lireSocketAdresseIn(void) { return(socketAdresseIn); }
> char* lireAdresseSocketAdresseIn(void) { return(inet_ntoa(socketAdresseIn.sin_addr)); }
> int lireSocketType(void) { return(socketType); }
> int lireSocketProtocol(void) { return(socketProtocol); }
> int lireFamilleSocketAdresseIn(void) { return(socketAdresseIn.sin_family); }
> unsigned short lirePortSocketAdresseIn(void) { return(socketAdresseIn.sin_port); }
> SOCKET lireSocketConnexion(void) { return(socketConnexion); }
> SOCKET* lireSocketConnexionRef(void) { return(&socketConnexion); }
> char* lireBufferEntree(void) { return(bufferEntree); }
> char* lireBufferSortie(void) { return(bufferSortie); }
> void ecrireAdresseSocketAdresseIn(char* a);
> void ecrireAdresseSocketAdresseInLocal(void);
> void ecrireSocketType(int t) { socketType = t; }
> void ecrireSocketProtocol(int p) { socketProtocol = p; }
> void ecrireSocketConnexion(SOCKET s) { socketConnexion = s; }
> void ecrireFamilleSocketAdresseIn(int f) { socketAdresseIn.sin_family = f; }
> void ecrirePortSocketAdresseIn(unsigned short& p) { socketAdresseIn.sin_port = htons(p); }
> void ecrireBufferEntree(char* chE) { bufferEntree = chE; }
> void ecrireBufferSortie(char* chS) { bufferSortie = chS; }
> int bindSocket(void);
> int creerSocket(void);
> int envoyer(void);
> int recevoir(void);
> void fermerSocket(void);
> int bloquerSocket(void);
> };
>
>
> /*** Initialiser la version de Winsock et demarre Winsock ***/
> int initialiserWinsock(void);
>
>
> #endif
> /************ socket.h ****************/
>
>
> /**************************/
> /* MA CLASSE SERVEUR
> /**************************/

> le type Liste est une liste dynamique sur un type quelconque
> elle derive de socketReseau
>
> /************ serveur.h ****************/
> #ifndef __SERVEUR__
> #define __SERVEUR__
>
> #include "listeGenerique.h" // Listes génériques
> #include "listeTemplate.h" // Listes templates
> #include "socket.h"
>
> #define SERVEUR_PRET true
> #define SERVEUR_INDISPONIBLE false
>
> class serveur : public socketReseau
> {
> private :
>
> bool status;
> int connexionMax;
> Liste<socketReseau> listeSocketsClients;
>
> public:
>
> serveur()
> {
> status = false;
> connexionMax = 5;
> listeSocketsClients.creerListe(socketReseau(), 1); // ici je cree une cellule socketReseau destine a recevoir le client
> }
> ~serveur();
> void creerListeSocketsClients(int nbC)
> {
> listeSocketsClients.creerListe(socketReseau(), nbC);
> }
> bool lireStatus(void) { return(status); }
> void ecrireStatus(bool s) { status = s; }
> char* AdresseIpDuClient(int numC);
> int envoyerClient(int numC, char* chOut);
> char* recevoirClient(int numC);
> int envoyerClients(char* chOutAll);
> int recevoirClients(char* chInAll);
> int demarrerServeur(unsigned short & port, int socType, int socFam);
> int ecouter(void);
> int attenteConnexionsClients(void);
> void arreterServeur(void);
> };
>
> #endif
> /************ serveur.h ****************/
>
>
> /**************************/
> /* MA CLASSE CLIENT
> /**************************/

>
> #ifndef __CLIENT__
> #define __CLIENT__
>
> #include "socket.h"
>
> class client : public socketReseau
> {
> private :
>
> char* adresseIPServeur;
>
> public:
> client(void) { }
> ~client(void) { }
>
> char* lireAdresseIPServeur() { return(adresseIPServeur); }
> void ecrireAdresseIPServeur(char* ch) { adresseIPServeur = ch;}
>
> int connexionServeur(char* adresseIPServeur, unsigned short & port, int socType, int socFam);
> int Connecter();
> void arreterClient();
> };
>
>
> #endif
> /************ serveur.h ****************/
>
>
>
> voici un aperçu du serveur.cpp
>
>
> /*** Destructeur ***/
> serveur::~serveur()
> {
> int k = 0;
> int erreur = 0;
>
> erreur = closesocket(listeSocketsClients[k].lireSocketConnexion());
> if (erreur == SOCKET_ERROR)
> {
> cerr << "Erreur Fermeture Socket Client pendant l'arret du serveur :" << WSAGetLastError() << endl;
> }
> WSACleanup(); // arret de winsock
> listeSocketsClients.detruireListe();
> }
>
> int serveur::demarrerServeur(unsigned short & port, int socType, int socFam)
> {
> int erreur = 0;
> this -> ecrireFamilleSocketAdresseIn(socFam);
> this -> ecrireSocketType(socType);
> this -> ecrireAdresseSocketAdresseInLocal();
> this -> ecrirePortSocketAdresseIn(port);
> this -> creerSocket();
> this -> bindSocket();
> if (this -> lireSocketConnexion() != INVALID_SOCKET)
> {
> cout << "SOCKET SERVEUR CREE AVEC SUCCES" << endl;
> cout << "ADRESSE : " << lireAdresseSocketAdresseIn() << endl;
> cout << "PORT : " << lireSocketAdresseIn().sin_port << endl;
> return(0);
> }
> else
> {
> cerr << "ERREUR LORS DE LA CREATION DU SOCKET SERVEUR" << endl;
> erreur = closesocket(this -> lireSocketConnexion());
> if (erreur == SOCKET_ERROR)
> {
> cerr << "Erreur fermeture socket serveur lors du demarrage suite a une erreur a la creation : " << WSAGetLastError() << endl;
> WSACleanup(); // arret de winsock
> return(INVALID_SOCKET);
> }
>
> return(INVALID_SOCKET);
> }
> return(0);
> }
>
>
>
>
> /*** Mise en ecoute du serveur ***/
> int serveur::ecouter(void)
> {
> if (listen(this -> lireSocketConnexion(), 0) == 0)
> {
> cout << "PASSAGE EN ECOUTE DU SERVEUR REUSSI" << endl;
> return(0);
> }
> else
> {
> cerr << "ERREUR LORS DU PASSAGE EN ECOUTE DU SERVEUR : " << WSAGetLastError() << endl;
> }
> return(SOCKET_ERROR);
> }
>
> /*** Attendre la connexion du client ***/
> int serveur::attenteConnexionsClients(void)
> {
> int tailleAdresse = 0;
>
> tailleAdresse = sizeof(struct sockaddr_in);
> listeSocketsClients[0].ecrireSocketConnexion(accept(this -> lireSocketConnexion(), (SOCKADDR*)listeSocketsClients[0].lireSocketAdresseInRef() ,&tailleAdresse));
> if (listeSocketsClients[0].lireSocketConnexion() != INVALID_SOCKET)
> {
> cout << "CONNECTION CLIENT ACCEPTEE" << endl;
> cout << "ADRESSE DU CLIENT : [" << listeSocketsClients[0].lireAdresseSocketAdresseIn() << "]" << endl;
> return(0);
> }
> else
> {
> cerr << "ERREUR LORS DU L'ACCEPTATION DU CLIENT : %d\n" << WSAGetLastError() << endl;
> return(SOCKET_ERROR);
> }
> return(0);
> }
>
> -------------------------------
> Réponse au message :
> -------------------------------
>
> > salut,
> >
> > moi je dirais que tu initialise la dll donc avec un WSAStartup,
> > ensuite tu initialiase la socket du "server", tu cree un nouveau thread dans lequel tu fais tourner un select (c'est mieux, 'fin je trouve) et enfin en fonction des FD tu transcrit le msg.
> >
> > Bon courage.
> >
> > Arno
> >
> >
> >
> > -------------------------------
> > Réponse au message :
> > -------------------------------
> >
> > > Salut,
> > >
> > > 1) WSA=> windows socket api => winsock 2
> > > Donc je pense pas que tu puisse utiliser les fonctions WSA en socket 1.1.
> > >
> > > 2) Ensuite, la fonction WSAAsyncSelect transcrit les evenement reseau en messages windows, donc il te faut une fenetre (meme invisible) pour recevoir et traiter les messages.
> > > Pour detecter et accepter une nouvelle connection, tu traite FD_ACCEPT. Dans ce message, ou plutot cette notification de message, tu met tout tes trucs: tu crée tes cellules, tu accepte la connection... Si accept retourne autre chose que INVALID_SOCKET, c'est que la connection a reussi.
> > >
> > > 3) Enfin, pour les erreurs de definition,
> > > - soit tu inclus winsock2.h avant windows.h (ca c si tu as juste des probs de redefinition avec winsock2.h)
> > > - soit tu met tout en haut, avant tout les header:
> > > #define _WIN32_WINNT 0x0500
> > > (c'est le mieux)
> > >
> > > 4) J'y connais rien en OPENGL, désolé.
> > >
> > >
> > > -------------------------------
> > > Réponse au message :
> > > -------------------------------
> > >
> > > > Bonjour,
> > > >
> > > > je devellope un jeu (2d + scene 3d) en Opengl et C++, je desire utiliser seulement opengl et c++ (console app), pour des raisons de portabilitée,donc pas de MFC !
> > > > et biensur j'aimerais que ce jeu ce joue en reseau :
> > > >
> > > > j'ai donc fais un client serveur tcp (winsock version 1.1)
> > > > mais les fonction accept et recv sont bloquante ,
> > > >
> > > > mon serveur passe en ecoute ,puis je fais un accept sur le socket client (1er client)
> > > > la fonction accept et bloquante !
> > > > j'ai donc cherché comment faire pour eviter ce probleme, et la je bloque un peu ?
> > > > j'ai bien vu des truc comme SWAAsyncSelect(socket,hWnd,wMsg,Event);
> > > >
> > > > comment reccuperer les messages de windows wMsg sous opengl et l'identificateur de la fenetre ?
> > > > pour que je puisse utiliser les fonctions du type WSA
> > > >
> > > >
> > > > je voudrais que le serveur detecte une nouvelle connexion cliente :
> > > > une fois mon serveur en ecoute je voudrais qu'il scrute les evenements network, pour faire selon un accept un send ou un recv.
> > > > le serveur possede une liste dynamique de socket client
> > > >
> > > > si evenement network FD_ACCEPT
> > > > creer cellule socket cliente
> > > > faire un accet sur ce socket
> > > > connexion acceptée ?
> > > >
> > > > scruter les evenements j'usqu'au prochain accept et on recommence, creation de la cellule socket cliente et accept...
> > > >
> > > > ainsi je pense que meme si la fonction accept et bloquante
> > > > vu que je detecte une demande de connexion avant de lancer la fonction accept, cela devrais fonctionner ?
> > > >
> > > > ou peut etre faut il utiliser les threads ,mais la j'ai pas tous compris !
> > > > comment utiliser un thread sous opengl sans MFC
> > > >
> > > > AUTRE SOUCIS :
> > > >
> > > > j'utilise winsock 1.1 car losrque j'inclus winsock2.h
> > > > avec la lib ws2_32.lib
> > > > j'ai des erreurs sur fd_set redefined etc......
> > > > impossible d'utiliser winsock version 2 !
> > > >
> > > > ya t'il un probleme dans windows.h, il me semble que winsock.h est systematiquement implementé ,ou quil manque des directives dans winsock2.h ?
> > > >
> > > > AUTRE QUESTION:
> > > >
> > > > quel est l'architecture d'un programme complex en opengl sans MFC,ou placer les traitements du programme ?
> > > > comme la getion des sockets reseau
> > > >
> > > > glutReshapeFunc(rafraichir);
> > > > glutIdleFunc(callBackFonction);
> > > > glutDisplayFunc(afficher);
> > > > glutMouseFunc(souris);
> > > > glutKeyboardFunc(clavier);
> > > >
> > > >
> > > > merci a vous de me donner un coup de main
> > > >
> > > >
> > >
> >
>
samedi 3 janvier 2004 à 14:16:06 | Re : Comment Gerer des sockets non bloquant sous OpenGl

kwisatz_haderach


Bonjour,
je fais le meme programme que toi : jeu openGL/C++ mais en utilisant DirectX pour l'input et l'audio (en prévision de rester sous Windows comme OS)
Si tu veux rajouter la fonctionnalité réseau, il faut créer une thread spécial réseau...
Le serveur possède 2 threads :
- ca boucle principal (thread SERVER_MAIN ) où il écoute, dispatche et envoie les informations aux sockets connectés
- une autre thread WAIT_CONNECTION qui s'occupe juste d'accepter les connections pour les ajouter au tableau des connectés.

Théoriquement dans la plupart des jeux que nous connaissons, la thread WAIT_CONNECTION est disponible qu'au moment où par exemple dans un wargame, on crée la salle et les autres rejoignent. Ensuite pendant le jeu, aucune connexion n'est souvent permise mais rien ne t'empeche de le faire comme tu le désires.

Pour t'expliquer les thread, je sais pas si tu aimes les articles en anglais mais voici la source que je me sers pour créer mes threads.. c'est une classe que je n'ai pas modifié dont je fais hérité mes classes thread comme networkThread ou encore gamecoreThread.... totalement compatible application dos par contre ce n'est pas cross-plateformable (ca existe comme mot ???) puisque sous unix/linux on utilise des commandes C systèmes pour créer les threads (enfin, je devrais dire "processus")

J'espère t'avoir un peu aider dans ta recherche...

le lien vers l'article Encapsulating Win32 threads in C++
http://www.codeproject.com/threads/thread_win32.asp


Cette discussion est classée dans : serveur, utiliser, opengl, accept, socket


Répondre à ce message

Sujets en rapport avec ce message

sockets: méthode accept() [ par julien20vt ] Voila,je viens de coder le serveur de ma socket et ce qui me parait etrange c'est que la méthode accept() n'est pas bloquante, je pensais que le serve Problème d'envoie par socket [ par CyberP ] J'ai fait un programme qui se connecte à un serveur ftp (le serveur ftp est aussi sur mon ordi). Je me connecte avec la fonction connect() et je recoi Tutorial - Socket, serveur, client BCPP + GUI [ par NyxArm ] Bonjours tout le monde, je suis présentement en période d'appretissage du language CPP sur Borland(v.6). Maintenant que j'ai acquis quelque conna socket et fichiers textes : HELP !! [ par ben01n ] Salut tout le monde !je prog actuellement un client serveur en udp multicast sous linux (voir source sur ce site) et j'aimerais que mon serveur envoi Serveur Vc++6 pb dans recv [ par alfred ] Salut a tousJ'ai un probleme dans mon serveur et je ne sais pas comment le resoudre. Le client se connecte bien et envoie le bon nombre de caracteres Recuperer un JPG sur serveur FTP [ par crocejf2000 ] Bonjour a tous,Peut etre que vous pourrez m'aider : je cherche a récuperer une image se trouvant a l'addresse "http://www.lesite.com/image.jpg".Donc a bind bought bought lier [ par JoebarGlut ] Salut, j'ai un piti problem de bind, kelkun peut il m'eclairer ?j'explik : (c'est un client qui se metamorphose en serveur ou en client suivant ce qu' pb connetion reseau multiutilisateurs [ par JRB ] lorsque l'on veut creer une connection reseau ou plusieurs clients peuvent se connecter sur le meme serveur, est ce que le serveur doit creer un socke Thread et socket besoin de conseil [ par kawito ] Salut,je desire realiser un client/serveur TCPle probleme est que les fonctions accept et recv sont bloquante.donc cela bloque l'affichage etc...mon p Connexion/Deconnexion/Reconnexion Socket [ par tequila1 ] BonjourJ'ai développé une DLL, qui se connecte à un serveur de données via socket.J'utilise pour cela les MFC. Je me connecte au serveur, je recois le


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,577 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales