LENOX8
Messages postés8Date d'inscriptionjeudi 30 mars 2006StatutMembreDernière intervention18 juillet 2006
-
1 avril 2006 à 20:07
l0st3d
Messages postés205Date d'inscriptionjeudi 19 décembre 2002StatutMembreDernière intervention13 novembre 2009
-
2 avril 2006 à 02:37
Salut tout le monde,
Merci pour toute les infos que vous m' avez donne, mais etant encore debutant je vois pas trop comment implantes les threads ainsi que leur synchronisation dans mon programme.
En fait j'ai realise un programme serveur SIP (VoIP) qui doit recevoir des messages des clients, les analyser puis enregistrer des donnees relatives au different client dans un liste chainee (cette liste doit etre mise a jour regulierement en tache de fond par une thread) puis les relayer vers les clients destinataires.
J'ai fait un programme de mise a jour dans un thread mais j'ai pas encore reussi a l'integrer dans le programme serveur et je suis perdu.
Si une personne saurait comment faire le rassemblement de mes deux program (faudrait que le serveur soit execute par une thread) il me serait d,un grand secours.
Merci à mon sauveur.
Ciao, bye
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contennant les données reçues ou envoyées
SOCKET id_envoi; // Identifiant de la socket
SOCKET id_recept; // Identifiant de la socket
SOCKADDR_IN info_envoi; // Déclaration de la structure des informations lié au serveur
SOCKADDR_IN info_recept;
char separateur2[N];
char tmp1[N];
char *mots1;
char adIP[N];
char ad_IP[N];
int flag=0;
/* flag
0->init
1->register
2->invite
3->
*/
list<tab_SIP> maliste;
list<tab_SIP>::iterator itliste;
list<tab_SIP>::iterator itlistetmp[N];//iterateur=pointeur de liste d'entier
tab_SIP elt1;
//affichage des chps des elets de la liste
void affichElem(list<tab_SIP> maliste,list<tab_SIP>::iterator itliste){
printf("\n");
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).timer << endl;//<<endl=saut de ligne
}
void InitPaq (PaqSip *p1){
strcpy(p1->typmsg,"REGISTER");
strcpy(p1->domain,"ief.org");
strcpy(p1->via," ");
strcpy(p1->from,"emetteur");
strcpy(p1->to,"serveur");
strcpy(p1->CallID," ");
strcpy(p1->timer,"0");
}
void AffichPaq(PaqSip p1){
printf("\n");
printf("typmsg=%s \n",p1.typmsg);
printf("domain=%s \n",p1.domain);
printf("via=%s \n",p1.via);
printf("from=%s \n",p1.from);
printf("to=%s \n",p1.to);
printf("CallID=%s \n",p1.CallID);
printf("timer= %s \n",p1.timer);
}
//paq en ligne->paq en struct
void InvMesLign(PaqSip *p1,char ligne[]){
char *mots;
char separateur[]="#";
int cptMot;
//recup le 1er mot de la chaine
mots=strtok(ligne,separateur);//etablir chaine et recup le premier mot
strcpy(p1->typmsg,mots);
cptMot=0;
while(mots!=NULL){
mots=strtok(NULL,separateur);//recup les prochains mots
cptMot++;
switch (cptMot){
case 1:
strcpy(p1->domain,mots);
break;
case 2:
strcpy(p1->via,mots);
break;
case 3:
strcpy(p1->from,mots);
break;
case 4:
strcpy(p1->to,mots);
break;
case 5:
strcpy(p1->CallID,mots);
break;
case 6:
strcpy(p1->timer,mots);
break;
default:
mots=NULL;//securite!
break;
}
}
}
//extrait le type du msg (/ex REGISTRAR)
void ExtraitMsg (PaqSip *p1){
char tmp[N];
char *mots;
char separateur[]=" ";
strcpy(tmp,p1->typmsg);
//recup le 1er mot de la chaine
mots=strtok(tmp,separateur);//etablir chaine et recup le premier mot
if(!strcmp(tmp,"REGISTER")) {
flag=1;
}
else if (!strcmp(tmp,"INVITE")) {
flag=2;
}
else if (!strcmp(tmp,"OK180")){
flag=3;
}
else if (!strcmp(tmp,"OK200")){
flag=4;
}
else if (!strcmp(tmp,"ACK")) {
flag=
}
else if (!strcmp(tmp,"BYE")) {
flag=6;
}
else {printf("msg inconnu! \n"); }
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
id_recept=socket(AF_INET,SOCK_DGRAM,0);
info_recept.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_recept.sin_addr.s_addr=INADDR_ANY; // Indiquez l'adresse IP de votre serveur
info_recept.sin_port=htons(33333); // Port TCP 33333 à destination du serveur
erreur=bind(id_recept,(struct sockaddr*)&info_recept,sizeof(info_recept));
tempo=sizeof(info_recept); // Passe par une variable afin d'utiliser un pointeur
nombre_de_caractere=recvfrom(id_recept,buffer,1515,0,(struct sockaddr*)&info_recept,&tempo);
buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recvfrom ne le fait pas
}
void Envoi(PaqSip p1,char adIP[]){
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
//envoi du register
id_envoi=socket(AF_INET,SOCK_DGRAM,0);
info_envoi.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_envoi.sin_addr.s_addr=inet_addr(adIP); // Indiquez l'adresse IP de votre serveur
info_envoi.sin_port=htons(33334); // Port TCP 33333 à destination du serveur
//printf("Data %s\n\n",MesLign(&p1));
strcpy(buffer,MesLign(&p1));// Copie la chaine de caractère dans buffer
printf("\n********************************** SERVEUR ***********************************\n");
while (1) {
PaqSip p1,p2,p3;
int flag2=0;
Recoit();
printf("\nVoici les donnees recues: %s\n",buffer);
//printf("Received packet from %s\nData: %s\n\n", inet_ntoa(info_recept.sin_addr)/*, ntohs(info_recept.sin_port)*/, buffer);
strcpy(ad_IP,inet_ntoa(info_recept.sin_addr));
printf("ad IP enregistre=%s \n",ad_IP);
InitPaq (&p1);
InvMesLign(&p1,buffer);
ExtraitMsg (&p1);
switch (flag){
case 1://->registrar init paq des 3 chps
strcpy( elt1.adIP,ad_IP);
strcpy( elt1.adSIP,p1.from);
elt1.timer=atoi(p1.timer);
maliste.push_back(elt1);
itliste = maliste.begin();
do{
affichElem(maliste,itliste);
if (!strcmp((*itliste).adSIP,p1.to)) strcpy(adIP,(*itliste).adIP);
itliste++;
}while(itliste!=maliste.end());
flag=0;
itliste = maliste.begin();//init le pt au debut de la liste
strcpy(p1.typmsg,"OK200");
Envoi(p1,adIP);//
printf("RENVOIE:::::::%s; IPdest=%s\n",buffer,adIP);
break;
case 2: //->Invite
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
strcpy(p1.via,adIP);//recup ip du dest pour ack
flag2=1;//recup IP ds table de ad sip du dest
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if(flag2==1){
strcpy(separateur2,"@");
strcpy(p1.typmsg,"INVITE");
strcat(p1.typmsg," ");
strcpy(tmp1,p1.to);
mots1=strtok(tmp1,separateur2);//etablir chaine et recup le premier mot
strcat(p1.typmsg,mots1);
strcat(p1.typmsg,separateur2);
strcat(p1.typmsg,adIP);
strcat(p1.typmsg," ");
strcat(p1.typmsg,version);
printf("redirection du Invite\n");
AffichPaq(p1);
flag=0;
Envoi(p1,adIP);
}else { flag=5;/*printf("flag5\n");getch();//pas ds la table*/
}
break;
case 3: //->ok180
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 4: //->ok200
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 5: //->ERREUR general 400
strcpy(adIP,inet_ntoa(info_recept.sin_addr));
strcpy(p1.typmsg,"ERREUR400");
AffichPaq(p1);
Envoi(p1,adIP);
case 6: //->bye
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
default :
break;
}
erreur=closesocket(id_recept);
}
#ifdef __WIN32__
system("PAUSE"); /* Pour la console Windows. */
#endif
return 0;
}
//////////////////////////////////////////////////////////CODE SOURCE MISE A JOUR///////////////////////////////////////////////////////////////////////////////
// TestThread.cpp : Defines the entry point for the console application.
//
/////////////////////////////////////////////////////
//mise à jour de la table evec les heure_expirations
/////////////////////////////////////////////////////
//affichage des chps des elets de la liste
void affichElem(list<SIP>::iterator itliste){
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).heure_expiration << endl;//<<endl=saut de ligne
}
void affichListeElem(list<SIP>::iterator itliste){
//affichage de la liste (/crs)
cout << "Liste" << endl;
itliste = maliste.begin();
do {
printf("\n");
affichElem(itliste);
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
int HeureCourante(){
struct tm *t;
time_t timestamp;
int heure_courante=0;
timestamp = time (NULL);
t = gmtime(×tamp);
heure_courante=((t -> tm_hour)*3600)+((t -> tm_min)*60)+t->tm_sec;
return heure_courante;
}
//parcours liste+affich elemts+met à jour la liste avec les heure_expirations
void MiseAJourTimer(list<SIP>::iterator itliste){
bool efface=0;
int i=0;
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (((*itliste).heure_expiration-HeureCourante())<=0){
itlistetmp[i]=itliste;
efface=1;
i++;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if (efface==1) {
while (i!=0){
maliste.erase(itlistetmp[i-1]);
printf("efface l'element car heure_expiration =0 \n\n");
i--;
}
}
}
//parcours liste+affich elemts+met à jour la liste avec les @sip
void MiseAJourSIP(list<SIP>::iterator itliste,char ad_IP[]){
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.from)){
strcpy((*itliste).adIP,ad_IP);
(*itliste).heure_expiration=HeureCourante()+3600;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
DWORD WINAPI ThreadFunc1( void* param)
{
list<SIP>::iterator itliste;
printf( "My thread ID is: %d\n", GetCurrentThreadId() );
do
{
Sleep(raffr);
affichListeElem(itliste);
MiseAJourTimer(itliste);
MiseAJourSIP(itliste,"192.192.192"/*nouvelleip*/);
affichListeElem(itliste);
/* wait for the thread to finish */
WaitForSingleObject( hThread1, INFINITE );
// WaitForSingleObject( hThread2, INFINITE );
/* clean up resources used by thread */
CloseHandle( hThread1 );
//CloseHandle( hThread2 );
}
Salut tout le monde,
Merci pour toute les infos que vous m' avez donne, mais etant encore debutant je vois pas trop comment implantes les threads ainsi que leur synchronisation dans mon programme.
En fait j'ai realise un programme serveur SIP (VoIP) qui doit recevoir des messages des clients, les analyser puis enregistrer des donnees relatives au different client dans un liste chainee (cette liste doit etre mise a jour regulierement en tache de fond par une thread) puis les relayer vers les clients destinataires.
J'ai fait un programme de mise a jour dans un thread mais j'ai pas encore reussi a l'integrer dans le programme serveur et je suis perdu.
Si une personne saurait comment faire le rassemblement de mes deux program (faudrait que le serveur soit execute par une thread) il me serait d,un grand secours.
Merci à mon sauveur.
Ciao, bye
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contennant les données reçues ou envoyées
SOCKET id_envoi; // Identifiant de la socket
SOCKET id_recept; // Identifiant de la socket
SOCKADDR_IN info_envoi; // Déclaration de la structure des informations lié au serveur
SOCKADDR_IN info_recept;
char separateur2[N];
char tmp1[N];
char *mots1;
char adIP[N];
char ad_IP[N];
int flag=0;
/* flag
0->init
1->register
2->invite
3->
*/
list<tab_SIP> maliste;
list<tab_SIP>::iterator itliste;
list<tab_SIP>::iterator itlistetmp[N];//iterateur=pointeur de liste d'entier
tab_SIP elt1;
//affichage des chps des elets de la liste
void affichElem(list<tab_SIP> maliste,list<tab_SIP>::iterator itliste){
printf("\n");
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).timer << endl;//<<endl=saut de ligne
}
void InitPaq (PaqSip *p1){
strcpy(p1->typmsg,"REGISTER");
strcpy(p1->domain,"ief.org");
strcpy(p1->via," ");
strcpy(p1->from,"emetteur");
strcpy(p1->to,"serveur");
strcpy(p1->CallID," ");
strcpy(p1->timer,"0");
}
void AffichPaq(PaqSip p1){
printf("\n");
printf("typmsg=%s \n",p1.typmsg);
printf("domain=%s \n",p1.domain);
printf("via=%s \n",p1.via);
printf("from=%s \n",p1.from);
printf("to=%s \n",p1.to);
printf("CallID=%s \n",p1.CallID);
printf("timer= %s \n",p1.timer);
}
//paq en ligne->paq en struct
void InvMesLign(PaqSip *p1,char ligne[]){
char *mots;
char separateur[]="#";
int cptMot;
//recup le 1er mot de la chaine
mots=strtok(ligne,separateur);//etablir chaine et recup le premier mot
strcpy(p1->typmsg,mots);
cptMot=0;
while(mots!=NULL){
mots=strtok(NULL,separateur);//recup les prochains mots
cptMot++;
switch (cptMot){
case 1:
strcpy(p1->domain,mots);
break;
case 2:
strcpy(p1->via,mots);
break;
case 3:
strcpy(p1->from,mots);
break;
case 4:
strcpy(p1->to,mots);
break;
case 5:
strcpy(p1->CallID,mots);
break;
case 6:
strcpy(p1->timer,mots);
break;
default:
mots=NULL;//securite!
break;
}
}
}
//extrait le type du msg (/ex REGISTRAR)
void ExtraitMsg (PaqSip *p1){
char tmp[N];
char *mots;
char separateur[]=" ";
strcpy(tmp,p1->typmsg);
//recup le 1er mot de la chaine
mots=strtok(tmp,separateur);//etablir chaine et recup le premier mot
if(!strcmp(tmp,"REGISTER")) {
flag=1;
}
else if (!strcmp(tmp,"INVITE")) {
flag=2;
}
else if (!strcmp(tmp,"OK180")){
flag=3;
}
else if (!strcmp(tmp,"OK200")){
flag=4;
}
else if (!strcmp(tmp,"ACK")) {
flag=
}
else if (!strcmp(tmp,"BYE")) {
flag=6;
}
else {printf("msg inconnu! \n"); }
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
id_recept=socket(AF_INET,SOCK_DGRAM,0);
info_recept.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_recept.sin_addr.s_addr=INADDR_ANY; // Indiquez l'adresse IP de votre serveur
info_recept.sin_port=htons(33333); // Port TCP 33333 à destination du serveur
erreur=bind(id_recept,(struct sockaddr*)&info_recept,sizeof(info_recept));
tempo=sizeof(info_recept); // Passe par une variable afin d'utiliser un pointeur
nombre_de_caractere=recvfrom(id_recept,buffer,1515,0,(struct sockaddr*)&info_recept,&tempo);
buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recvfrom ne le fait pas
}
void Envoi(PaqSip p1,char adIP[]){
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
//envoi du register
id_envoi=socket(AF_INET,SOCK_DGRAM,0);
info_envoi.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_envoi.sin_addr.s_addr=inet_addr(adIP); // Indiquez l'adresse IP de votre serveur
info_envoi.sin_port=htons(33334); // Port TCP 33333 à destination du serveur
//printf("Data %s\n\n",MesLign(&p1));
strcpy(buffer,MesLign(&p1));// Copie la chaine de caractère dans buffer
printf("\n********************************** SERVEUR ***********************************\n");
while (1) {
PaqSip p1,p2,p3;
int flag2=0;
Recoit();
printf("\nVoici les donnees recues: %s\n",buffer);
//printf("Received packet from %s\nData: %s\n\n", inet_ntoa(info_recept.sin_addr)/*, ntohs(info_recept.sin_port)*/, buffer);
strcpy(ad_IP,inet_ntoa(info_recept.sin_addr));
printf("ad IP enregistre=%s \n",ad_IP);
InitPaq (&p1);
InvMesLign(&p1,buffer);
ExtraitMsg (&p1);
switch (flag){
case 1://->registrar init paq des 3 chps
strcpy( elt1.adIP,ad_IP);
strcpy( elt1.adSIP,p1.from);
elt1.timer=atoi(p1.timer);
maliste.push_back(elt1);
itliste = maliste.begin();
do{
affichElem(maliste,itliste);
if (!strcmp((*itliste).adSIP,p1.to)) strcpy(adIP,(*itliste).adIP);
itliste++;
}while(itliste!=maliste.end());
flag=0;
itliste = maliste.begin();//init le pt au debut de la liste
strcpy(p1.typmsg,"OK200");
Envoi(p1,adIP);//
printf("RENVOIE:::::::%s; IPdest=%s\n",buffer,adIP);
break;
case 2: //->Invite
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
strcpy(p1.via,adIP);//recup ip du dest pour ack
flag2=1;//recup IP ds table de ad sip du dest
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if(flag2==1){
strcpy(separateur2,"@");
strcpy(p1.typmsg,"INVITE");
strcat(p1.typmsg," ");
strcpy(tmp1,p1.to);
mots1=strtok(tmp1,separateur2);//etablir chaine et recup le premier mot
strcat(p1.typmsg,mots1);
strcat(p1.typmsg,separateur2);
strcat(p1.typmsg,adIP);
strcat(p1.typmsg," ");
strcat(p1.typmsg,version);
printf("redirection du Invite\n");
AffichPaq(p1);
flag=0;
Envoi(p1,adIP);
}else { flag=5;/*printf("flag5\n");getch();//pas ds la table*/
}
break;
case 3: //->ok180
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 4: //->ok200
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 5: //->ERREUR general 400
strcpy(adIP,inet_ntoa(info_recept.sin_addr));
strcpy(p1.typmsg,"ERREUR400");
AffichPaq(p1);
Envoi(p1,adIP);
case 6: //->bye
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
default :
break;
}
erreur=closesocket(id_recept);
}
#ifdef __WIN32__
system("PAUSE"); /* Pour la console Windows. */
#endif
return 0;
}
//////////////////////////////////////////////////////////CODE SOURCE MISE A JOUR///////////////////////////////////////////////////////////////////////////////
// TestThread.cpp : Defines the entry point for the console application.
//
/////////////////////////////////////////////////////
//mise à jour de la table evec les heure_expirations
/////////////////////////////////////////////////////
//affichage des chps des elets de la liste
void affichElem(list<SIP>::iterator itliste){
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).heure_expiration << endl;//<<endl=saut de ligne
}
void affichListeElem(list<SIP>::iterator itliste){
//affichage de la liste (/crs)
cout << "Liste" << endl;
itliste = maliste.begin();
do {
printf("\n");
affichElem(itliste);
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
int HeureCourante(){
struct tm *t;
time_t timestamp;
int heure_courante=0;
timestamp = time (NULL);
t = gmtime(×tamp);
heure_courante=((t -> tm_hour)*3600)+((t -> tm_min)*60)+t->tm_sec;
return heure_courante;
}
//parcours liste+affich elemts+met à jour la liste avec les heure_expirations
void MiseAJourTimer(list<SIP>::iterator itliste){
bool efface=0;
int i=0;
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (((*itliste).heure_expiration-HeureCourante())<=0){
itlistetmp[i]=itliste;
efface=1;
i++;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if (efface==1) {
while (i!=0){
maliste.erase(itlistetmp[i-1]);
printf("efface l'element car heure_expiration =0 \n\n");
i--;
}
}
}
//parcours liste+affich elemts+met à jour la liste avec les @sip
void MiseAJourSIP(list<SIP>::iterator itliste,char ad_IP[]){
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.from)){
strcpy((*itliste).adIP,ad_IP);
(*itliste).heure_expiration=HeureCourante()+3600;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
DWORD WINAPI ThreadFunc1( void* param)
{
list<SIP>::iterator itliste;
printf( "My thread ID is: %d\n", GetCurrentThreadId() );
do
{
Sleep(raffr);
affichListeElem(itliste);
MiseAJourTimer(itliste);
MiseAJourSIP(itliste,"192.192.192"/*nouvelleip*/);
affichListeElem(itliste);
/* wait for the thread to finish */
WaitForSingleObject( hThread1, INFINITE );
// WaitForSingleObject( hThread2, INFINITE );
/* clean up resources used by thread */
CloseHandle( hThread1 );
//CloseHandle( hThread2 );
}
Salut tout le monde,
Merci pour toute les infos que vous m' avez donne, mais etant encore debutant je vois pas trop comment implantes les threads ainsi que leur synchronisation dans mon programme.
En fait j'ai realise un programme serveur SIP (VoIP) qui doit recevoir des messages des clients, les analyser puis enregistrer des donnees relatives au different client dans un liste chainee (cette liste doit etre mise a jour regulierement en tache de fond par une thread) puis les relayer vers les clients destinataires.
J'ai fait un programme de mise a jour dans un thread mais j'ai pas encore reussi a l'integrer dans le programme serveur et je suis perdu.
Si une personne saurait comment faire le rassemblement de mes deux program (faudrait que le serveur soit execute par une thread) il me serait d,un grand secours.
Merci à mon sauveur.
Ciao, bye
WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
int tempo; // Variable temporaire de type int
int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
char buffer[65535]; // Tampon contennant les données reçues ou envoyées
SOCKET id_envoi; // Identifiant de la socket
SOCKET id_recept; // Identifiant de la socket
SOCKADDR_IN info_envoi; // Déclaration de la structure des informations lié au serveur
SOCKADDR_IN info_recept;
char separateur2[N];
char tmp1[N];
char *mots1;
char adIP[N];
char ad_IP[N];
int flag=0;
/* flag
0->init
1->register
2->invite
3->
*/
list<tab_SIP> maliste;
list<tab_SIP>::iterator itliste;
list<tab_SIP>::iterator itlistetmp[N];//iterateur=pointeur de liste d'entier
tab_SIP elt1;
//affichage des chps des elets de la liste
void affichElem(list<tab_SIP> maliste,list<tab_SIP>::iterator itliste){
printf("\n");
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).timer << endl;//<<endl=saut de ligne
}
void InitPaq (PaqSip *p1){
strcpy(p1->typmsg,"REGISTER");
strcpy(p1->domain,"ief.org");
strcpy(p1->via," ");
strcpy(p1->from,"emetteur");
strcpy(p1->to,"serveur");
strcpy(p1->CallID," ");
strcpy(p1->timer,"0");
}
void AffichPaq(PaqSip p1){
printf("\n");
printf("typmsg=%s \n",p1.typmsg);
printf("domain=%s \n",p1.domain);
printf("via=%s \n",p1.via);
printf("from=%s \n",p1.from);
printf("to=%s \n",p1.to);
printf("CallID=%s \n",p1.CallID);
printf("timer= %s \n",p1.timer);
}
//paq en ligne->paq en struct
void InvMesLign(PaqSip *p1,char ligne[]){
char *mots;
char separateur[]="#";
int cptMot;
//recup le 1er mot de la chaine
mots=strtok(ligne,separateur);//etablir chaine et recup le premier mot
strcpy(p1->typmsg,mots);
cptMot=0;
while(mots!=NULL){
mots=strtok(NULL,separateur);//recup les prochains mots
cptMot++;
switch (cptMot){
case 1:
strcpy(p1->domain,mots);
break;
case 2:
strcpy(p1->via,mots);
break;
case 3:
strcpy(p1->from,mots);
break;
case 4:
strcpy(p1->to,mots);
break;
case 5:
strcpy(p1->CallID,mots);
break;
case 6:
strcpy(p1->timer,mots);
break;
default:
mots=NULL;//securite!
break;
}
}
}
//extrait le type du msg (/ex REGISTRAR)
void ExtraitMsg (PaqSip *p1){
char tmp[N];
char *mots;
char separateur[]=" ";
strcpy(tmp,p1->typmsg);
//recup le 1er mot de la chaine
mots=strtok(tmp,separateur);//etablir chaine et recup le premier mot
if(!strcmp(tmp,"REGISTER")) {
flag=1;
}
else if (!strcmp(tmp,"INVITE")) {
flag=2;
}
else if (!strcmp(tmp,"OK180")){
flag=3;
}
else if (!strcmp(tmp,"OK200")){
flag=4;
}
else if (!strcmp(tmp,"ACK")) {
flag=
}
else if (!strcmp(tmp,"BYE")) {
flag=6;
}
else {printf("msg inconnu! \n"); }
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
id_recept=socket(AF_INET,SOCK_DGRAM,0);
info_recept.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_recept.sin_addr.s_addr=INADDR_ANY; // Indiquez l'adresse IP de votre serveur
info_recept.sin_port=htons(33333); // Port TCP 33333 à destination du serveur
erreur=bind(id_recept,(struct sockaddr*)&info_recept,sizeof(info_recept));
tempo=sizeof(info_recept); // Passe par une variable afin d'utiliser un pointeur
nombre_de_caractere=recvfrom(id_recept,buffer,1515,0,(struct sockaddr*)&info_recept,&tempo);
buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recvfrom ne le fait pas
}
void Envoi(PaqSip p1,char adIP[]){
erreur=WSAStartup(MAKEWORD(2,2),&initialisation_win32);
//envoi du register
id_envoi=socket(AF_INET,SOCK_DGRAM,0);
info_envoi.sin_family=AF_INET; // Indiquez l'utilisation d'IPV4
info_envoi.sin_addr.s_addr=inet_addr(adIP); // Indiquez l'adresse IP de votre serveur
info_envoi.sin_port=htons(33334); // Port TCP 33333 à destination du serveur
//printf("Data %s\n\n",MesLign(&p1));
strcpy(buffer,MesLign(&p1));// Copie la chaine de caractère dans buffer
printf("\n********************************** SERVEUR ***********************************\n");
while (1) {
PaqSip p1,p2,p3;
int flag2=0;
Recoit();
printf("\nVoici les donnees recues: %s\n",buffer);
//printf("Received packet from %s\nData: %s\n\n", inet_ntoa(info_recept.sin_addr)/*, ntohs(info_recept.sin_port)*/, buffer);
strcpy(ad_IP,inet_ntoa(info_recept.sin_addr));
printf("ad IP enregistre=%s \n",ad_IP);
InitPaq (&p1);
InvMesLign(&p1,buffer);
ExtraitMsg (&p1);
switch (flag){
case 1://->registrar init paq des 3 chps
strcpy( elt1.adIP,ad_IP);
strcpy( elt1.adSIP,p1.from);
elt1.timer=atoi(p1.timer);
maliste.push_back(elt1);
itliste = maliste.begin();
do{
affichElem(maliste,itliste);
if (!strcmp((*itliste).adSIP,p1.to)) strcpy(adIP,(*itliste).adIP);
itliste++;
}while(itliste!=maliste.end());
flag=0;
itliste = maliste.begin();//init le pt au debut de la liste
strcpy(p1.typmsg,"OK200");
Envoi(p1,adIP);//
printf("RENVOIE:::::::%s; IPdest=%s\n",buffer,adIP);
break;
case 2: //->Invite
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
strcpy(p1.via,adIP);//recup ip du dest pour ack
flag2=1;//recup IP ds table de ad sip du dest
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if(flag2==1){
strcpy(separateur2,"@");
strcpy(p1.typmsg,"INVITE");
strcat(p1.typmsg," ");
strcpy(tmp1,p1.to);
mots1=strtok(tmp1,separateur2);//etablir chaine et recup le premier mot
strcat(p1.typmsg,mots1);
strcat(p1.typmsg,separateur2);
strcat(p1.typmsg,adIP);
strcat(p1.typmsg," ");
strcat(p1.typmsg,version);
printf("redirection du Invite\n");
AffichPaq(p1);
flag=0;
Envoi(p1,adIP);
}else { flag=5;/*printf("flag5\n");getch();//pas ds la table*/
}
break;
case 3: //->ok180
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 4: //->ok200
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
case 5: //->ERREUR general 400
strcpy(adIP,inet_ntoa(info_recept.sin_addr));
strcpy(p1.typmsg,"ERREUR400");
AffichPaq(p1);
Envoi(p1,adIP);
case 6: //->bye
//parcours liste+affich elemts+met à jour la liste avec les @sip
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.to)){
strcpy(adIP,(*itliste).adIP);
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
flag=0;
Envoi(p1,adIP);
break;
default :
break;
}
erreur=closesocket(id_recept);
}
#ifdef __WIN32__
system("PAUSE"); /* Pour la console Windows. */
#endif
return 0;
}
//////////////////////////////////////////////////////////CODE SOURCE MISE A JOUR///////////////////////////////////////////////////////////////////////////////
// TestThread.cpp : Defines the entry point for the console application.
//
/////////////////////////////////////////////////////
//mise à jour de la table evec les heure_expirations
/////////////////////////////////////////////////////
//affichage des chps des elets de la liste
void affichElem(list<SIP>::iterator itliste){
cout << (*itliste).adIP << endl;//<<endl=saut de ligne
cout << (*itliste).adSIP << endl;//<<endl=saut de ligne
cout << (*itliste).heure_expiration << endl;//<<endl=saut de ligne
}
void affichListeElem(list<SIP>::iterator itliste){
//affichage de la liste (/crs)
cout << "Liste" << endl;
itliste = maliste.begin();
do {
printf("\n");
affichElem(itliste);
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
int HeureCourante(){
struct tm *t;
time_t timestamp;
int heure_courante=0;
timestamp = time (NULL);
t = gmtime(×tamp);
heure_courante=((t -> tm_hour)*3600)+((t -> tm_min)*60)+t->tm_sec;
return heure_courante;
}
//parcours liste+affich elemts+met à jour la liste avec les heure_expirations
void MiseAJourTimer(list<SIP>::iterator itliste){
bool efface=0;
int i=0;
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (((*itliste).heure_expiration-HeureCourante())<=0){
itlistetmp[i]=itliste;
efface=1;
i++;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
if (efface==1) {
while (i!=0){
maliste.erase(itlistetmp[i-1]);
printf("efface l'element car heure_expiration =0 \n\n");
i--;
}
}
}
//parcours liste+affich elemts+met à jour la liste avec les @sip
void MiseAJourSIP(list<SIP>::iterator itliste,char ad_IP[]){
itliste = maliste.begin();//init le pt au debut de la liste
do{
if (!strcmp((*itliste).adSIP,p1.from)){
strcpy((*itliste).adIP,ad_IP);
(*itliste).heure_expiration=HeureCourante()+3600;
}
itliste++;//iterateur++
}while(itliste!=maliste.end());//parcours la liste tant qu'on est pas à la fin
}
DWORD WINAPI ThreadFunc1( void* param)
{
list<SIP>::iterator itliste;
printf( "My thread ID is: %d\n", GetCurrentThreadId() );
do
{
Sleep(raffr);
affichListeElem(itliste);
MiseAJourTimer(itliste);
MiseAJourSIP(itliste,"192.192.192"/*nouvelleip*/);
affichListeElem(itliste);
MrdJack
Messages postés146Date d'inscriptionjeudi 22 avril 2004StatutMembreDernière intervention 8 mars 20082 2 avril 2006 à 01:01
faudrait elaguer un peu cette source pour que l'on puisse cibler les parties du code les plus concernées...
et puis je comprend pas pourquoi tu as autant de fonctions main() dans ce code... normallement une seule suffit !
cette fonction main() va créer ton thread gérant le serveur donc ca
cible une fonction qui gere le serveur, je rappelle qu'un thread est
comme une boucle main(), elle peut créer d'autres threads etc...
dans ce cas, la fonction du serveur créée un autre thread pour recevoir les données en non bloquant...
je sais pas trop si tu piges ce que je veux dire mais le mieux, c'est
de faire en sorte que ton programme principal fonctionne, et que d'un
autre coté, tu progs une fonction gérant le serveur mais que cettte
fonction soit indépandante du prog principal. mis a part les mutex qui
permettent un acces aux meme données depuis l'un ou l'autre des
processus.