| | 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
|
| | |
| |
| 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) | | | | | 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 ... | | | | | 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. | | | | | 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 ^^
| | | | | camje_lemon | Posté le 20/01/2004 à 21:23 | Petit astucien
35 Messages
| Le recu j'en ai besoin et le * ossi ^^ (apres test ^^) | | | |
| | 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
|
|