> Tous les forumsAutres langages

 C and Socket sous linux
Statut du sujet : NON RESOLU Imprimer
 camje_lemon
  Posté le 18/01/2004 @ 21:36  
 Petit astucien

35 Messages
Bonsoir, J'ai le code ci-dessous, je le met sur un dédié via shell, je lance la compilation avec GCC, 0erreur et tout et tout. Mais il se trouve que le programme a de drôles de reactions et à pas l'air de trop fonctionner :/ Ce n'est que une première version ;). Sinon pouvez vous me dire si vous voyez des choses mal codé ou qui pourrait posé probleme. Merci Voila le code :
#include <stdio.h> #include <string.h> #include <signal.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <sys/types.h> #include <sys/time.h> //Creation de la commande delay (n'existant pas sous Linux) sleep sous win void recu(){} void delay(unsigned int millisecondes) { int nn; struct itimerval value; signal(SIGALRM,recu); getitimer(ITIMER_REAL,&value); if (millisecondes<1000) { value.it_value.tv_sec=0; value.it_value.tv_usec=1000*millisecondes; } else { value.it_value.tv_sec=(int)(millisecondes/1000); value.it_value.tv_usec=0; } setitimer(ITIMER_REAL,&value,NULL); nn=pause(); } //---------------->Fin de la creation de delay typedef struct sockaddr_in SOCKADDR_IN; //Structure clients typedef struct _client client; struct _client { int Socket;//Le socket du gars | ou struct socket Socket; mé marse ^p char* HostName;//Sont hostname char Port[6];//Le portk il utilise (ya po trop de possiiblité lol, mé si je fé un multi port ^^) char IP[16];//Son ip ^^ char IfIP;//Si j'ai eu son Hostname char IfPseudo;//Si j'ai eu son Pseudo char* Pseudo;//Son pseudo, si jlai pas, bah c l'ip ^^ on peut la changé en envoyant un message ki commence par RAW NICK client*next;//c pour le -> ^^ }; /* Info : Pour accéder à un membre de la structure il faut faire précéder son nom par un point (.) et par le nom de la variable utilisée. Ou, si on utilise une variable pointeur, il faut faire précéder son nom par une flèche (->) et par le nom de la variable. */ //Envoyer un msg a tout le monde ^^ void SendAll(char* msg,client*kl) { client*kt; for(kt=kl->next;kt != NULL;kt=kt->next) { sprintf(msg, "%s\n\r", msg); send(kt->Socket,msg,sizeof(msg),0); } } int main() { client*klist; //Pointeur des derniers mis, afin den ajouter a la suite sans rien perdre ^^ client*ktmp; //pointeur tmp pour se deplacer dans la liste client*vlist; //Pour lajout char* tmp; char* buf;//Buf recpt : Commande char* buf1;//Avant decoupage char* buf3;//Buf recpt : apres Commande char* Bsend; int len,ret,taille,i,strV; int SClient; struct hostent* InfoC; char* buffer;//chaine de carractere du buffer (512char-\n\r) SOCKADDR_IN ServSock; SOCKADDR_IN ClientSock; int sd,nbref=0,nbuser=0; //nbref = 1er argument select for nux fd_set recois; struct timeval temps; signal(SIGPIPE,SIG_IGN); //eviter broken pipe a la deco d'un gars klist=NULL; //0element dans la liste = null, on lutilise ke pour lajout ^^ vlist=(client*)malloc(sizeof(client));//Jen met un vide pour reperer le debut vlist->next=klist;//On le remplit de NULL klist=vlist;//On met Klist au suivant ktmp=NULL; //tmps null //Connection = Serveur sd = socket(AF_INET, SOCK_STREAM, 0); if(sd==-1) { perror("socket");exit(0); } ServSock.sin_family = AF_INET; ServSock.sin_addr.s_addr = inet_addr("0.0.0.0"); ServSock.sin_port = htons(2000); if (bind (sd,(struct sockaddr*)&ServSock,sizeof(ServSock))==-1) { perror("bind"); exit(0); } if(listen(sd,20)) { perror("listen"); exit(0); } printf("Serveur lancé. Port 2000 ouvert. PVsend Serveur by camje_lemon"); len=sizeof(SOCKADDR_IN); // while(recv(sock,buffer,strlen(buffer),0)) while(1) { // delay(50); cpu or not cpu that the question loool ^^ jparle bien anglais nop ? FD_ZERO(&recois); FD_SET(sd,&recois); if(nbref<sd) nbref=sd; //On cherche le socket ac la valeur la plus elevé : for(ktmp=klist->next;ktmp!=NULL;ktmp=ktmp->next)//regarde 1 par 1 { if(nbref<ktmp->Socket) nbref=ktmp->Socket; FD_SET(ktmp->Socket,&recois); } temps.tv_sec=0; //}Tps max av select sock change temps.tv_usec=0;//} ret=select(nbref+1,&recois,NULL,NULL,&temps); if(FD_ISSET(sd,&recois)) { //Si le flux de sd se modify alors, nouveau client SClient=accept(sd,(struct sockaddr*) &ClientSock,&len); //on utlise la socket en tete de liste chainée qui été vide if(nbref<klist->Socket) nbref=klist->Socket; //tjs pr le select if (klist->Socket == -1) perror("accept"); else { vlist=(client*)malloc(sizeof(client)); vlist->next; vlist->Socket = SClient; sprintf(vlist->Port, "%i", ClientSock.sin_port); sprintf(vlist->IP, "%s", inet_ntoa(ClientSock.sin_addr)); sprintf(vlist->Pseudo, "%s", inet_ntoa(ClientSock.sin_addr)); InfoC = gethostbyaddr((char*) &(ClientSock.sin_addr.s_addr), 4, AF_INET); if (InfoC) { vlist->HostName = (char*) malloc(strlen(InfoC->h_name)); strcpy(vlist->HostName, InfoC->h_name); vlist->IfIP = 0; } else { vlist->HostName = (char*) malloc(strlen("UNKNOWN_HOST")); strcpy(vlist->HostName, "UNKNOWN_HOST"); vlist->IfIP = 1; } vlist->IfPseudo = 0; nbuser++; klist=vlist; Bsend="En attente du nickname (commande : nick)\n\r"; send(SClient,Bsend,sizeof(Bsend),0); } //un nouvel élément est crée } for(ktmp=klist->next;ktmp != NULL;ktmp=ktmp->next)//on regarde si on a racu un truc d'i, client { if(FD_ISSET(ktmp->Socket,&recois)) { //on mate si un des flux a changé de chak élément taille=recv(ktmp->Socket,buffer,500,0); //si oui on récup les infos if(taille>500) taille=500; //on tronk la chaine si elle trop grosse (evite les overflow) if(taille == 0 || taille == -1) { //c'est si le client déco nbuser--; close(ktmp->Socket); // facon nux if (ktmp->IfPseudo == 1) { sprintf(tmp, "%s est parti.", ktmp->Pseudo); SendAll(tmp,klist); } free(tmp); //JARTAGE ^^ } else//Ici on gere les msg recu { buf1 = strdup(&buffer[taille]); buf = strtok(buf1, " "); buf3 = strtok(NULL, "\n"); if (strcmp(buf,"nick") == 0)//Change Nick { strV=strlen(buf3); if (strV > 20) buf3=&buf3[20]; if (ktmp->IfPseudo == 0) { sprintf(tmp, "On:%s", ktmp->Pseudo); SendAll(tmp,klist); ktmp->IfPseudo == 1; } else { sprintf(tmp, "Nick:%s %s", ktmp->Pseudo, buf3); SendAll(tmp,klist); ktmp->IfPseudo == 1; } ktmp->Pseudo=buf3; }//Cnick end if (strcmp(buf,"msg") == 0)//send msg { sprintf(tmp, "MSG:%s %s.", ktmp->Pseudo, buf3); SendAll(tmp,klist); }//send end } } } }//while }//main
 Afficher le profil de camje_lemonEnvoyer un message privé à camje_lemon
 
 
Publicité
 camje_lemon  Posté le 18/01/2004 à 21:39  
Petit astucien

35 Messages
PS : En + de chose surement flagrantes et mal codé par moi, je ne suis pas sur du bien allé de ma Structure (n'ai pas pu testé :P)
Afficher le profil de camje_lemonEnvoyer un message privé à camje_lemon
 Revenir en haut de la page
 koala01  Posté le 20/01/2004 à 13:06  
Astucien

4715 Messages
la première chose qui attire mon regard est void recu(){}... une proédure vide , c'est pas tres courent [clindoeil] La deuxieme chose qui m'intrigue quelque peu est int main() { En effet, la boucle principale (main) n'est pas censer renvoyer une valeur... On utilise généralement void main(){} ou void main(void){} en fonction du langage (c, c++) car main ne doit renvoyer aucune valeur et ne doit, en principe, pas non plus en réclamer [clindoeil] La troisième chose est que ton typedef ne m'a pas l'air correct ... typedef struct sockaddr_in SOCKADDR_IN; //Structure clients typedef struct _client client; struct _client { int Socket;//Le socket du gars | ou struct socket Socket; mé marse ^p char* HostName;//Sont hostname char Port[6];//Le portk il utilise (ya po trop de possiiblité lol, mé si je fé un multi port ^^) char IP[16];//Son ip ^^ char IfIP;//Si j'ai eu son Hostname char IfPseudo;//Si j'ai eu son Pseudo char* Pseudo;//Son pseudo, si jlai pas, bah c l'ip ^^ on peut la changé en envoyant un message ki commence par RAW NICK client*next;//c pour le -> ^^ }; Ne serait-ce pas plutot typedef struct sockaddr_in SOCKADDR_IN; //Structure clients typedef struct _client* client; struct _client { int Socket;//Le socket du gars | ou struct socket Socket; mé marse ^p char* HostName;//Sont hostname char Port[6];//Le portk il utilise (ya po trop de possiiblité lol, mé si je fé un multi port ^^) char IP[16];//Son ip ^^ char IfIP;//Si j'ai eu son Hostname char IfPseudo;//Si j'ai eu son Pseudo char* Pseudo;//Son pseudo, si jlai pas, bah c l'ip ^^ on peut la changé en envoyant un message ki commence par RAW NICK client*next;//c pour le -> ^^ }_client; [question] En quatrième lieu, je te conseillerais plutot de mettre tes boulces void delay(unsigned int millisecondes) et void SendAll(char* msg,client*kl) APRES la boucle principale (main()) Enfin mais je me suis peut etre trompé en réindentant, j'ai l'impression que tu fermes une accolade de trop à la fin de main ...
Afficher le profil de koala01 Voir la configuration de koala01Envoyer un message privé à koala01
  Revenir en haut de la page
 Patator  Posté le 20/01/2004 à 15:18  
Astucien

1883 Messages
koala01 a écrit : La deuxieme chose qui m'intrigue quelque peu est int main() {
C'est tout à fait normal. [url]http://www.eskimo.com/~scs/readings/voidmain.960823.html[/url] Les deux se font. Main prend en général deux arguments: argc et argv qui sont le nombres de paramètres, nom de l'application comprise et les paramètres en question.
Afficher le profil de PatatorEnvoyer un message privé à Patator
 Revenir en haut de la page
 camje_lemon  Posté le 20/01/2004 à 21:22  
Petit astucien

35 Messages
Donc je vois un peu pres. pour le recu ca gene pas trop c le code du delay sous Linux c le même a plusieur endroit je pense que c'est bon. Je vais vour pour le * de typedef struct _client* client; ^^ En quatrième lieu, je te conseillerais plutot de mettre tes boulces void delay(unsigned int millisecondes) et void SendAll(char* msg,client*kl) APRES la boucle principale (main()) Je v voir ^^ peut être que le compiler a laissé passer l'erreur, je ferai les tests demain et vous direz la reponse ^^ Merci ^^
Afficher le profil de camje_lemonEnvoyer un message privé à camje_lemon
 Revenir en haut de la page
 camje_lemon  Posté le 20/01/2004 à 21:23  
Petit astucien

35 Messages
Le recu j'en ai besoin et le * ossi ^^ (apres test ^^)
Afficher le profil de camje_lemonEnvoyer un message privé à camje_lemon
 Revenir en haut de la page
Haut de la page 
Inscrivez-vous !
- Posez vos questions

- Résolvez vos problèmes

- Aidez les autres

- Participez et créez vos discussions

- Dialoguez en privé avec d'autres membres

- Suivez vos sujets préférés

- Affichez les signatures des membres

TOUT EST GRATUIT !

Je crée mon compte



Vous avez besoin d'aide ?
Des centaines d'experts sont à votre disposition sur les forums PC Astuces pour vous aider gratuitement, 24h/24, 7j/7.

Les derniers sujets résolus !
 

 > Tous les forumsAutres langages

 
Forum PC Astuces© 1997-2008 WebastucesAller en haut de la page