pb socket

 
Poster un nouveau sujet   Répondre au sujet    iprelax.fr Index du Forum -> C sous UNIX et Windows
Voir le sujet précédent :: Voir le sujet suivant  
Auteur Message
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Lun Nov 18, 2002 4:37 pm    Sujet du message: pb socket Répondre en citant

Bonjour

je suis en train de développer un client/serveur. Au niveau serveur lorsqu'on attend une socket client on utilise la fonction accept:

socket_client = accept(socket_serveur_descr,(struct sockaddr *)&client,&taille_client);


Le pb c'est que cette fonction est bloquante et tant qu'il n'y a pas de socket client à se connecter la fonction attend. Comment y remédier?

Touti
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Lun Nov 18, 2002 4:42 pm    Sujet du message: Répondre en citant

un exemple de socket non bloquante avec select :
http://www.salemioche.com/outils/c_prog3.php
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Mar Nov 19, 2002 11:07 am    Sujet du message: Répondre en citant

question supplémentaire. J'ai vu qu'avec le select on pouvait savoir si une demande de connexion de socket était en attente. Maintenant dans le cas que j'ai une connexion entre mon serveur et mon client, est ce que je peux savoir si mon client m'a envoyé un message (si je l'ai reçu plutot) en utilisant la commande select ou bien faut il que je passe forcément par la commande recv.

Touti
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Mar Nov 19, 2002 12:24 pm    Sujet du message: Répondre en citant

le mieux est de gérer la connexion dans un thread independant pour
eviter tout probleme de blocage
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Mar Nov 19, 2002 2:15 pm    Sujet du message: Répondre en citant

désolé pas compris la réponse.

Pour être plus précis, la fonction select sert uniquement à savoir si une demande de connexion est adressé au serveur ou bien a t'elle d'autres fonctionnalités que je ne connais pas? Par exemple m'avertir si un message est arrivé (équivalent du recv).
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Mar Nov 19, 2002 8:42 pm    Sujet du message: Répondre en citant

select()--Multiplexage Synchrone d'E/S
Cette fonction a quelque chose d'étrange, mais elle est TRES UTILE. Prenez la situation suivante: vous êtes un serveur et vous voulez attendre une connexion entrante mais aussi garder la connection que vous avez déjà.

Pas de problème vous vous dites, un simple accept() et deux appels à recv(). Pas si vite! Que se passera t-il s-il y a un blocage sur un accept()? Comment allez vous recevoir des données avec recv() en même temps? Utilisez des sockets non_bloquante!Pas question! Vous ne voulez pas être un consommateur record de CPU? Quoi alors ?

select() vous offre le possibilité de surveiller plusieurs sockets en même temps. Cela va vous permettre de savoir laquelle est prête à la lecture ou à l'écriture et si une exception se produit sur une socket si vous voulez réellement le savoir.

Sans plus de palabres, voici le prototype de select():

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int select(int numfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

La fonction surveille des ensembles de descripteurs de fichiers et plus particulierement readfds, writefds, et exceptfds. (On parlera d'ensemble pour parler d'ensemble de descripteur de fichier) Si vous voulez voir si vous pouvez lire à partir de l'entrée standard et sur quelques sockets , ajoutez les descripteurs de fichiers 0 et sockfd à l'ensemble readfds. Le paramètre numfds doit être mis à la valeur du fichier le plus haut plus un. Dans cet exemple, il doit être mis a sockfd+1, assurant ainsi qu'il est supérieur a l'entrée standard (0).

Quand select() se termine, readfds sera modifié avec la fonction réflexe disant que le descripteur de fichier que vous avez sélectionné est près a la lecture. Vous pouvez les tester avec les macros FD_ISSET(), suivantes.

Avant d'aller plus avan , je vais vous expliquer comment manipuler ces ensembles. Chaque ensemble est de type fd_set. Les macros suivantes agissent sur ce type:

FD_ZERO(fd_set *set) - initialise l'ensemble
FD_SET(int fd, fd_set *set) - Ajoute fd à l'ensemble
FD_CLR(int fd, fd_set *set) - Elimine fd de l'ensemble
FD_ISSET(int fd, fd_set *set) - test pour savoir si fd fait parti de l'ensemble

Finalement, qu'est ce que c'est que cette struct timeval sortie de la jungle? Bien, il y a des moment ou vous ne voulez pas attendre une éternité que quelqu'un vous envoi des données. Peut être que toutes les 96 secondes vous voulez afficher "En cours..." sur le terminal même si rien ne se passe. Cette structure dédiée au temps vous autorise à spécifier un TIMEOUT. Si cette période s'achève et que select() n'a pas trouvé de descripteurs prêt, alors la fonction prendra la main et le programme continuera.

La struct timeval contient les champs suivants:

struct timeval {
int tv_sec; /* secondes */
int tv_usec; /* microsecondes */
};

Affectez à tv_sec le nombre de secondes à attendre, et à tv_usec le nombre de micro-secondes. Oui, ce sont des microsecondes, et non des millisecondes. Il y a 1000 micro-seconds dans une millisecondes et 1 000 000 micro-secondes dans une secondes. Pour alors cela s'appelle t-il "usec" ? Le "u" est en fait la lettre grec Mu utilisée ici pour dire micro. Alors, au retour de la fonction, timeout peut être mit à jour pour indiquer combien de temps il reste. Cela dépends de la couleur de l'Unix que vous utilisez.

Yeah! Nous avons un chronomètre précis à la micro-seconde! Mais ne comptez pas trop dessus. Les Unix standards ont une résolution temporelle de 100 milliseconds, alors vous aurez probablement à attendre au moins ce temps, même si vous réglez votre struct timevalà une valeur plus petite.

Autre point intéressant: Si vous positionnez les champs de votre structure struct timeval à 0, select() fera un timeout immédiatement, et interrogera tous les descripteurs de fichier dans vos ensembles. Si vous mettez le paramètre timeout a NULL, il ne fera jamais de timeout, et attendra que le premier descripteur soit prêt. Finalement, si vous n'êtes pas intéressé par une attente quelconque, vous pouvez passez à select() , NULL comme paramètre.

L'exemple suivant attends 2.5 secondes que quelques choses arrive sur l'entrée standard:

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#define STDIN 0 /* Descripteur de fichier pour entrée standard */

main()
{
struct timeval tv;
fd_set readfds;

tv.tv_sec = 2;
tv.tv_usec = 500000;

FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);

/* ignorer writefds et exceptfds: */
select(STDIN+1, &readfds, NULL, NULL, &tv);

if (FD_ISSET(STDIN, &readfds))
printf("Une touche à été pressée!\n");
else
printf("Timed out.\n");
}

Si vous lancez ce programme à partir d'un terminal (qui bufferise la ligne), vous devrez appuyer sur la touche RETURN ou il y aura un time out.

Maintenant, plusieurs d'entre vous peuvent pensez que c'est là la bonne méthode pour attendre les données sur une socket datagram -- et vous avez raison cela peut l'être. Certain unix implémentent select pour cette utilisation, et d'autres non. Vous devriez regarder les pages de manuel de votre système pour savoir de quelles manière vous allez aborder le problème.

Pour conclure sur l'appel système select(): si vous avez une socket qui est en train d'écouter avec listen(), vous pouvez regarder si il y a une nouvelle connection en mettant le descripteur de socket dans l'ensemble readfds .
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Mer Nov 20, 2002 5:23 pm    Sujet du message: Répondre en citant

ok merci.

autre question, comment faire en sorte que la fonction recv ne soit pas bloquante si mon client ne m'envoie rien?
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Mer Nov 20, 2002 5:38 pm    Sujet du message: Répondre en citant

il faut utiliser le flag MSG_DONTWAIT
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Mer Nov 20, 2002 5:44 pm    Sujet du message: Répondre en citant

et où je le positionne?
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Mer Nov 20, 2002 5:53 pm    Sujet du message: Répondre en citant

en 4eme parametre
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
touti
jeune mioche
jeune mioche


Inscrit le: 16 Oct 2002
Messages: 46

MessagePosté le: Mer Nov 20, 2002 6:06 pm    Sujet du message: Répondre en citant

j'ai une erreur à la compil, il ne connait pas le flag MSG_DONTWAIT.
que faire?
je rappelle que je suis sous visual C++ et que je code en C.
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé
Salemioche
salemioche
salemioche


Inscrit le: 05 Avr 2002
Messages: 350
Localisation: FR- BIOT

MessagePosté le: Mer Nov 20, 2002 6:22 pm    Sujet du message: Répondre en citant

oups, mea culpa. desole, les winsocks sont un grand mystere pour moi Crying or Very sad
_________________
Creer son site - Hebergement - Jumeaux
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Visiter le site web du posteur Yahoo Messenger MSN Messenger
ttbidouille
jeune mioche
jeune mioche


Inscrit le: 21 Juin 2002
Messages: 10

MessagePosté le: Mer Déc 04, 2002 6:39 pm    Sujet du message: Répondre en citant

Socket sous VC (Sans MFC)

tu doit utiliser le WSAAsyncSelect(..) pour ne pas blocker sous Visual C++
cette fonction pour asynchrone le Socket ....

MFC:
Class CSocket et CAsyncSocket ..
voir MSDN ....

ttbidouille
_________________
ttbidouille@yahoo.com
Revenir en haut
Voir le profil de l'utilisateur Envoyer un message privé Envoyer un email
Montrer les messages depuis:   
Poster un nouveau sujet   Répondre au sujet    iprelax.fr Index du Forum -> C sous UNIX et Windows Toutes les heures sont au format CET (Europe)
Page 1 sur 1

 
Sauter vers:  
Vous ne pouvez pas poster de nouveaux sujets dans ce forum
Vous ne pouvez pas répondre aux sujets dans ce forum
Vous ne pouvez pas éditer vos messages dans ce forum
Vous ne pouvez pas supprimer vos messages dans ce forum
Vous ne pouvez pas voter dans les sondages de ce forum
Affilzen SARL : Mention légale