Accueil > Forum > > > > fonction accepte bloquante..
fonction accepte bloquante..
mercredi 9 août 2006 à 23:46:20 |
fonction accepte bloquante..

ssmint
|
Bonjour à tous, nouveau problème de socket, côté server cette fois ci : imaginons que plusieurs clients cherchent à se connecter sur le port d'écoute du server en même temps, je voudrais pouvoir recevoir toutes les connections puis choisir celle avec laquelle dialoguer...
=>Je fais donc un tableau de sock[] avec une boucle stoquant dans chaque sock les infos necessaires grâce à la fonction accept(), le problème, c'est que le socket server étant bloquant par défaut, la fonction accept() aussi.. Ce qui fait que la boucle bloque si il n'y a pas assez de conection entrantes. Dans mon code, j'ai pris 5 connections max mais s'il n'y en a que 2 ça ne marchepas , la boucle bloque sur la fonction accept()!!
=> Du coup, pas de problème : je rend donc le socket non bloquant grâce à la fonction ioctlsocket()!!
=> Sauf que du coup j'ai un autre problème lors de la communication avec le client, la fonction recv() n'est pas bloquante! Alors c'est franchement chiant pour dialoguer, il faut mettre la fonction recv() dans une boucle infini pour recevoir un truc, compte tenu ds fonctionnalités que je veux mettre dans le prog, c'est impossible...
J'aimerais donc savoir si c'est possible de mettre une sorte de timeout sur la fonction accept() avec un socket bloquant ou "rerendre" le socket bloquant après avoir choisi le client (se que j'ai essayé mais qui ne marche pas)...
Voici mon code :
#include <stdio.h> #include <winsock2.h> #include <string.h>
int main() { // variables WSADATA wsa; SOCKET server; //Le socket qui servira à écouter sur un port SOCKET sock[5]; //les sockets qui serviront à communiquer SOCKADDR_IN sinserv; //parametres pour server SOCKADDR_IN sin[5]; //parametres pour socks
char buffer[50], *P, *ip; int sinsize; int i=0, c,tmp;
// Présentation : system("color a"); system("cls"); system("TITLE TCP server by ssmint");
// Mise en place de l'écoute : WSAStartup(MAKEWORD(2,2),&wsa); sinserv.sin_family = AF_INET; sinserv.sin_addr.s_addr = INADDR_ANY; sinserv.sin_port=htons(1234);
server = socket(AF_INET,SOCK_STREAM,0); bind(server,(SOCKADDR*)&sinserv,sizeof(sinserv));
listen(server,5); // Socket rendu non bloquant : u_long p=1; ioctlsocket(server, FIONBIO,&p);
// Affichage connections et choix : printf("\nEcoute sur le port 1234. ..\t (3 sec)\n\n"); Sleep(3000);//necessaire pour mettre connection en queue printf("Connexions recues :\t(5 max)\n"); memset(buffer,sizeof(buffer),0); sinsize=sizeof(sin); while((sock[i]=accept(server,(SOCKADDR*)&sin[i],&sinsize))!=INVALID_SOCKET) { ip = inet_ntoa(sin[i].sin_addr); //affichage ip client... printf("\n [%d] %s ",i+1,ip); i++; } // Pas de connections : if(sock[0]==INVALID_SOCKET) { printf("\n\tAucune\n\n"); system("pause"); WSACleanup(); exit(0); } // Choix de la connection pour dialogue : printf("\n=> Selection connection: "); scanf("%d", &c); c--; // Fermeture des sockets inutilisés : for(i=0; i<5; i++) { if(i!=c) { closesocket(sock[i]); } }
p=0; // NE FONCTIONNE PAS!!! ioctlsocket(server, FIONBIO,&p); //une fois la fonction accept() passé //le socket server reste non-bloquant system("pause"); }
Merci d'avance désolé pour le "pavé".
|
|
jeudi 10 août 2006 à 06:41:38 |
Re : fonction accepte bloquante..

nightlord666
|
Pour ça, tu met ta boucle infinie avec recv dans un thread que tu aura créé. Regarde sur developpez.com, il y a un article sur les serveurs multithreads.
Sachant qu'on peut toujours enlever une ligne à un programme, et que dans un programme il y a toujours un bug, un programme peut se résumer à une ligne avec un bug.
|
|
jeudi 10 août 2006 à 09:52:07 |
Re : fonction accepte bloquante..

turnerom
|
Re, il faut que tu utilise la fonction select, voici un exemple de code qui marche (version Linux par contre mais l'idée est la, c'est + ou - la meme chose sous WinWin) Ce code permet a nombre illimité (enfin presque 64511 pour etre precis) de client de se connecter, et lui envoi le fichier passer en paramètre.
int
main
(
int
argc, char*argv[]) {
intds,port,ta,da,sock; structsockaddr_inname;
if(argc!=2)/* Test Le nombre d'arguments */ { fprintf(stderr,"Usage : ./serveur port \n"); exit(0); }
puts("Serveur en attente");/*Message d'attente*/ puts("");
port=atoi(argv[1]);/*L'argument 1 est le numero de port sur lequel le serveur attend*/
ds=socket(PF_INET, SOCK_STREAM, 0);/*On crée notre socket de connection*/
if(ds<0)/*Avec un test pour éviter les erreurs*/ { perror("Probleme socket : "); exit(-1); }
init_sockaddr(&name,"0.0.0.0",port);/*On initialise notre socket internet, le port ecoute sur toute les adresse*/
if(bind(ds, (structsockaddr*)&name, sizeof(structsockaddr))<0)/*On bind*/ {/*Avec un test pour éviter les erreurs*/ perror("Probleme bind : "); exit(-1); }
if(listen(ds, FILED)<0)/*On listen dans notre socket de connexion jusqu'à "FILED" client max*/ {/*Avec un test pour éviter les erreurs*/ perror("Probleme listen "); exit(-2); }
while(1)/*Serveur multi-client donc boucle infinie*/ {
FD_ZERO(listeClients);/*On reinitialise notre liste d'attente*/ FD_SET(ds,listeClients);/*Dans laquelle on place notre socket de connexion*/
if((select(FILED+1, listeClients, NULL, NULL,NULL))<0)/*On fait notre select sur notre liste de client*/ {/*Avec un test pour éviter les erreurs*/ perror("select"); exit(-3); }
for(sock=3;sock<FILED;sock++)/*On parcourt toutes nos (potentielles) sockets*/ {
if(FD_ISSET(sock,listeClients))/*On regarde quelle descripteur change d'etat*/ { if(sock==ds)/*Si c'est la socket de connection...*/ { da=accept(ds, (structsockaddr*)&name, &ta);/*...on l'accepte...*/ if(da<0)/*...toujours avec un test pour éviter les erreurs...*/ { perror("Probleme accept "); exit(-3); } printf("Connexion socket n°%d établie\n",da); FD_SET(da,listeClients);/*...et on la rajoute dans notre liste de clients*/ } elsetraiterClient(sock);/*Si ce n'est pas la socket de connection, c'est alors une socket de data*/ /*On appelle donc notre fonction de transfert proprement dite en passant en argument...*/ }/*...la socket où le client envoi son fichier*/ }
}
close(da); close(ds);
return0; }
voidinit_sockaddr(structsockaddr_in*name, constchar*hostname, uint16_tport) { structhostent*hostinfo;
name->sin_family=AF_INET;/* Adresses IPV4 (Internet) */ name->sin_port=htons(port);/* On gère le little/big Endian */
hostinfo=gethostbyname(hostname);/* appeler les fonctions de résolution de nom de la libC */
if(hostinfo==NULL)/* Si ne peut transformer le nom de la machine en adresse IP */ { fprintf(stderr, "Unknown host %s.\n", hostname); exit(-1); } name->sin_addr=*(structin_addr*)hostinfo->h_addr;/* Le dernier champs de la structure est garni */ }
voidtraiterClient(intda) { charbuffer[SIZE],nomFich[SIZE]; intfich; ssize_tsize;
if(read(da,nomFich,SIZE)<0)/*On récupere le nom du fichier*/ {/*Avec toujours un petit test pour éviter les erreurs*/ perror("Nom de fichier non recu : "); exit(-4); }
if(nomFich==NULL)/*Avec meme un 2eme test pour être totalement sûr*/ { perror("Nom de fichier invalide"); exit(-5); }
/*Si tout es bon...*/ fich=open(nomFich,O_WRONLY|O_CREAT,777/*,S_IRWXU|S_IRWXG|S_IRWXO*/);/*On ouvre le fichier (ou on le cree s'il n'existe pas) en lecture seule avec le nom recu*/ /* voir (1) en bas de page*/ puts("Réception en cours...");
while((size=read(da,buffer,SIZE)))write(fich,buffer,size);/*Tant que c'est pas la fin du fichier on lit dans la socket et on ecrit dans le fichier*/
puts("Réception terminée"); puts("");
close(da);/*On ferme la socket...*/ close(fich);/*...et le fichier*/
}
TuRn3r
|
|
jeudi 9 septembre 2010 à 15:05:33 |
Re : fonction accepte bloquante..

ZapaN28
|
ssmint a dit :
"je rend donc le socket non bloquant grâce à la fonction ioctlsocket()!"
merci je connaissais pas ! ca va m'aider nikel
Zap ;)
|
|
Cette discussion est classée dans : fonction, server, socket, sin, sock
Répondre à ce message
Sujets en rapport avec ce message
Probleme sockets de mer** [ par zzzzzz ]
bé je suis plus quoi faire j'en suis toujours au meme prob y'en a 1 qui me dit d'utiliser strstr() l'autre strcmp() fin bref ca serrais sympas si quel
Probleme de Client Serveur [ par Krox68 ]
voila jaimerais faire un programme client qui puisse se connecter a ce serveur : #include void main(){ WSADATA WSAData; WSAStartup(MAKEWORD(2,0), &WS
LERREUR QUI TUE §§§§§§§§§§§§§§§§ [ par Avalon10101 ]
Vla jai fé mon prog tout é juste mais ya une erreur que je narrive vraiment pas à comprendre ! :C:\Documents and Settings\Alex\Mes documents\Makefile.
pb socket [ par surfeurnet ]
voici mon programme qui a pour l'instant pour unique but de se connecter à un serveur :# include # include # pragma comment (lib,"w32_32.lib")char ip,
prob sock [ par epoc ]
voilà, g commencé la prog des socks en vc++, mais rien ne transitte alors que la connexion semble être bien effectuée, voilà le code :****************
[SOCKET]Tjrs le pb de recuperation du buffer recv() [ par enthaz ]
Allez J me lance : ca fait des heures et des heures ke le newb ke je suischerche la solution :D un coté j ai un logiciel client ki envoie "coucou" sur
Socket, quand tu nous tiens ... [ par enthaz ]
Allez J me lance : ca fait des heures et des heures ke le newb ke je suischerche la solution :D un coté j ai un logiciel client ki envoie "coucou" sur
Pb de socket 'winsock2.h' [ par amodels ]
Bonjour tlm.Je voudrais éxécuter l'adresse http://127.0.0.1/toto.php avec ce code :#include #include #pragma comment(lib, "ws2_32.lib")void main(){WS
PROB SOCKETS CON [ par zzzzzz ]
le code source marche mais quand je rajoute un cout#include #pragma comment(lib,"ws2_32.lib")#include int main(void)
erreur 10038 [ par made_in_france ]
Hello ! j'ai un probleme avec la fonction bind de mon programme. En effet cette fonction me renvois l'erreur 10038 « attempted ». Est ce que quelqu'un
Livres en rapport
|
Derniers Blogs
JOYEUX ANNIVERSAIRE NIXJOYEUX ANNIVERSAIRE NIX par ebartsoft
Souhaitons un bon et joyeux anniversaire à notre hôte à tous, Nix.
Je ne le répéterais jamais assez mais sans lui rien ne serait possible. Il défit en permanence les lois de la gravité et comme il le dit si bien, si tu lui fais confiance ça devra...
Cliquez pour lire la suite de l'article par ebartsoft 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
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
|