Accueil > Forum > > > > Comment Gerer des sockets non bloquant sous OpenGl
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
|
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
Livres en rapport
|
Derniers Blogs
IMAGINE CUP 2012, MAKE A SIGN EN FINALEIMAGINE CUP 2012, MAKE A SIGN EN FINALE par junarnoalg
Voilà qui est fait, la nouvelle est officielle ! L'équipe belge "Make a Sign" va au pays des kangourous défendre son projet dans la catégorie Software Design. http://www.imaginecup.com/CompetitionsContent/Competition/WorldwideFinalists.aspx V...
Cliquez pour lire la suite de l'article par junarnoalg KINECT 1.5 IS OUT !KINECT 1.5 IS OUT ! par Vko
La version 1.5 du Kinect For Microsoft vient tout juste de sortir ! Plein de nouveautés: Tracking de squelette en Near Mode Détection en position assise Détection faciale avec un SDK dédié Documentation et des guideline (enfin) Un out...
Cliquez pour lire la suite de l'article par Vko LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) LES ACTUALITéS DE LA SEMAINE SUR C2I.FR (14 MAI - 20 MAI) par richardc
Mise à jour des Web API du 14 Mai
Réservez dès maintenant votre journée du 20 juin pour le Windows Azure Dev Camp 2012 à Paris
Mise à jour de Team Foundation Service
MechCommander 2 sur Windows 8
Entity Framework 5 Release Candidate e...
Cliquez pour lire la suite de l'article par richardc REACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITERREACTIVE EXTENSIONS : CONSOMMER DES SERVICES AVEC RX PARTIE 3, LES PIèGES à éVITER par Groc
Une mauvaise utilisation de rx lors de l'écriture d'une couche d'accès à des services peut conduire à des cas embarassants avec des erreurs mal gérées, des appels qui ne partent lorsqu'ils le devraient, et même des résultats incorrects . le tout nuis...
Cliquez pour lire la suite de l'article par Groc SHAREPOINT BLOG SITE, PROBLèME D'ARCHIVESSHAREPOINT BLOG SITE, PROBLèME D'ARCHIVES par junarnoalg
Dernièrement, nous avons migré le site
myTIC
vers un nouveau serveur SharePoint 2010. Dans les contenus que nous vouloins récupérer, nous avions un certain nombre de blogs.
Nous avons utilisé les commandes Power...
Cliquez pour lire la suite de l'article par junarnoalg
Logiciels
sDEVIS-FACTURES vlPRO (8.1.0.3)SDEVIS-FACTURES VLPRO (8.1.0.3)sDEVIS-FACTURES vlPRO a été mis au point pour les particuliers, créateurs, entrepreneurs, artisa... Cliquez pour télécharger sDEVIS-FACTURES vlPRO 974 Application Server (12.2.4.6)974 APPLICATION SERVER (12.2.4.6)Développez de puissantes applications dans un environnement de 'cloud computing', clusterisé, séc... Cliquez pour télécharger 974 Application Server vPicture (1.4.2.1)VPICTURE (1.4.2.1)Avec vPicture, hébergez vos images facilement et rapidement.
vPicture est un utilitaire simple, ... Cliquez pour télécharger vPicture Easy-Planning (2.2.1.6)EASY-PLANNING (2.2.1.6)Easy-Planning permet de créer des plannings sous la représentation de diagrammes et est adapté au... Cliquez pour télécharger Easy-Planning COM-BACKUP (2.0)COM-BACKUP (2.0)
COM-BACKUP est un logiciel de sauvegarde qui permet de planifier les sauvegardes de vos dossiers ...
Cliquez pour télécharger COM-BACKUP
|