arconius | Bonjour à tous tout d'abord
Je bloque actuellement sur un problème que je trouve personnellement compliquer. En gros pour vous situer le contexte, je programme un Doomlike en OpenGl. Je code actellement la partie réseau, seulement chaque personnage ou balle est caractérisée par un structure de double :
struct tir
{
double x,y,z,angleTX,angleTZ;
};
(les angles c pour le calcul des directions)
chaque élement est stocké dans un tableau permetant d'être représenter sur chaque pc ensuite :
tir tirs[800];
tir vaiss[8];
maintenant mon problème :
Comme vous le savez pour l'envoie de packet via des sockets on utilise les fonctions send et recv. Or ceux ci requier un tableau de char en paramètre. Il me faut donc convertir mes tableaux de structures de double en tableau de char.
je vous passe le code qui me bloque : (je sais c super lourd de regarder un code comme ça alors j'ai essayer de le commenter, je n'ai aucune erreur de compilation, c juste que ça plante sur un memcpy je crois durant l'execution :s)
Code :
- #include <stdio.h>
- #include <winsock.h>
- #define TAILLE 50
- struct tir
- {
- double x,y,z,angleTX,angleTZ;
- };
- SOCKET sock[7],sock_attente,sockc;
- char buffserv[8080],buffcli[20];
- SOCKADDR_IN csin;
- SOCKADDR_IN sin1;
- int sinsize;
- unsigned long ioctl_opt =1;
- fd_set readfds;
- tir buffglob[808],buffpt[2];
- bool serv = false;
- bool jeu = false;
- void serveur() //fonction pour initialiser le mode serveur
- {
- WSADATA WSAData; //Nécéssaire au sockets made in Windows
- WSAStartup(MAKEWORD(1,1), &WSAData);
- FD_ZERO(&readfds); //fd_set sera utiliser pour rendre recv non bloquant
-
- sinsize = sizeof(sin1);
- sin1.sin_addr.s_addr = INADDR_ANY; //construction de mon socket
- sin1.sin_family = AF_INET;
- sin1.sin_port = htons(200); //le port que l'on désire ouvrir
- sock_attente = socket(AF_INET, SOCK_STREAM, 0);
- bind(sock_attente, (SOCKADDR *)&sin1, sinsize);
- listen(sock_attente, 7); //permet d'accepter jusqu'à 7 client
- ioctlsocket(sock_attente,FIONBIO,&ioctl_opt); //sockets en mode non bloquants
- }
- int client() //initialisation du mode client
- {
- char ret[2];
- WSADATA WSAData;
- WSAStartup(MAKEWORD(1,1), &WSAData);
-
- FD_ZERO(&readfds);
-
- sockc = socket(AF_INET, SOCK_STREAM, 0);
-
- sinsize = sizeof(sin1);
-
- sin1.sin_addr.s_addr = inet_addr("127.0.0.1" );
- sin1.sin_family = AF_INET;
- sin1.sin_port = htons(200); // le port que l'on désire ouvrir
-
- connect(sockc, (SOCKADDR *)&sin1, sinsize);
- FD_SET(sockc,&readfds); //permet de rendre la fonction recv non bloquante
- select(0,&readfds,0,0,NULL);
- if(FD_ISSET(sockc,&readfds))
- recv(sockc,ret,2,0); //ici je reçoit mon numéro de client
- return atoi(ret);
- }
- void ecoute(int *i) //fonction permetant au serveur d'accepter les connection de nouveau client
- {
- char ret[2];
- FD_SET(sock_attente,&readfds); //pour rendre accept non bloquant
- select(0,&readfds,0,0,NULL);
- if (FD_ISSET(sock_attente, &readfds))
- {
- sock[*i] = accept(sock_attente, (SOCKADDR *)&csin, &sinsize);
- FD_SET(sock[*i],&readfds);
- *i++;
- send(sock[*i],itoa(*i,ret,10),80,0); //j'envoie au nouveau client son numéro
- }
- }
- void env_rec(int nbcli,int *nbtir,bool serv,tir tirs[800],tir vaiss[8]) //fonction d'envoie reception
- {
- int k;
- if(!serv) //reception coté client
- {
- tir cli[2];
- cli[0]=tirs[*nbtir];
- cli[1]=vaiss[nbcli];
- memcpy((void *)buffcli,(const void *)cli,80); //je copie les coordonnée de mon vaisseau et de mon dernier tir dans le buffer
- send(sockc,buffcli,80,0); //j'envoie
- FD_ZERO(&readfds); //je réinitialise mon ensemble de socket
- FD_SET(sockc,&readfds); //je rend recv non bloquant
- select(0,&readfds,0,0,NULL);
- if(FD_ISSET(sockc,&readfds))
- {
- recv(sockc,buffserv,32320,0); //ici je reçois les coordonnées de l'ensemble des tirs et vaisseau
- }
- memcpy((void*)buffglob,(const void*)buffserv,32320);
- for(k=0;k<800;k++) //je réordonne tout ça
- tirs[k]=buffglob[k];
- for(k=800;k<808;k++)
- vaiss[k-800]=buffglob[k];
- }
- else //reception coté serveur
- {
- int i;
- for(i=0;i<800;i++) //copie de l'ensemble des coordonnées dans un tableau
- buffglob[i]=tirs[i];
- for(i=800;i<808;i++)
- buffglob[i]=vaiss[i-800];
- memcpy((void*)buffserv,(const void*)buffglob,32320); //copie de ce tableau dans un buffer
- for(k=0;k<nbcli;k++)
- send(sock[k],buffserv,32320,0); //envoie de ces coordonnées à tous les clients
- for(k=0;k<nbcli;k++) //reception des coordonnées de tous les clients
- {
- FD_SET(sock[k],&readfds);
- select(0,&readfds,0,0,NULL);
- if(FD_ISSET(sock[k],&readfds))
- recv(sock[k],buffcli,80,0);
- memcpy((void*)buffpt,(const void*)buffcli,80);
- if(buffpt[0].x>-TAILLE && buffpt[0].x<TAILLE)//si les coordonnées du tir sont dans la zone de jeu je les copies
- {
- tirs[*nbtir]=buffpt[0];
- *nbtir++;
- if(*nbtir==800) *nbtir=0;
- }
- vaiss[k]=buffpt[1];
- }
- }
- }
- void main()
- {
- static int i,j=0,test=0,nbcli=0,nbtirs=0,T=0;
- tir tirs[800];
- tir vaiss[8];
- //Menu
- printf("\t 1 - Mode serveur (Echap pour quitter une fois connecter)\n" );
- printf("\t 2 - Mode client\n\n\n" );
- printf("Choix :" );
- scanf("%d",&i);
- //Mode serveur
- while(1)
- {
- if(i==1)
- {
- serv=true;
- if(!jeu)
- {
- serveur();
- jeu=TRUE;
- }
- ecoute(&nbcli);
- T=nbcli;
- }
- //Mode client
- else if (i==2)
- {
- if(!jeu)
- {
- T=client();
- jeu=TRUE;
- nbcli=T;
- }
- }
- if(jeu)
- env_rec(nbcli,&nbtirs,serv,tirs,vaiss);
- }
- }
|
Message édité par arconius le 03-06-2005 à 18:20:25
|