IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Sock Recv


Sujet :

Réseau C

  1. #1
    Membre éclairé Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Points : 876
    Points
    876
    Par défaut Sock Recv
    Bonjour,

    Je voudrai savoir,

    avec recv, y'a t-il des chances pour que si plusieur clients m'envois des données plus longues que ce que je recupère dans mon recv ou que le client segmente en petites parties, que je recoivent ensuite celle de l'un puis de l'autre dans n'importe quel ordre, ou est ce que je vais recevoir l'un après l'autre ? étant donné que j'utilise poll() pour gérer les files descriptors, poll ne va t-il pas passé à un autre socket meme si recv n'a pas fini son travail ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (recv(poll_list[i].fd, pSock, 1, 0) < 1) {
    	if (poll_list[i].fd != s_listen) {
    		poll_list[i].fd = -1;
    	}
    } else {
    	// traitement de pSock
    }
    Merci j'espère que vous avez compris

  2. #2
    Membre actif Avatar de keil
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    261
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 261
    Points : 214
    Points
    214
    Par défaut
    tel que je le vois, tu demandes de lire un caractere dans une socket.

    n'oublie pas que recv attend un message avant d'executer la suite de ton code.

    je suppose aussi que ton bout de code est inclus dans une boucle qui incrémente i.

    donc tel que je le vois, ton prog attend un caractere d'une socket, puis gere le caractere recu et va lire la socket suivante pour refaire le meme traitement etc...

    deja je me demande si recv(-1, ...) entraine pas un segmentation fault.
    puis j'ai jamais utilisé un buffer plus court que la taille d'un message envoyé.

    n'oublie pas qu'en C, un message est envoyé lorsque la chaine se termine par un antislash-n.
    ce qui veut dire qu'en attribuant une taille de 1 de lecture de buffer, tu auras certainement des problemes par la suite.
    je te conseillerai plutot de recuperer la grande chaine envoyée, de créer une pile dans laquelle tu empileras l'un après l'autre, tous les caractères reçus, que tu dépileras dans ton traitement de pSock.
    Colère et Haine mènent à la Puissance

  3. #3
    Membre éclairé Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Points : 876
    Points
    876
    Par défaut
    Biensûre que je ne recupère pas que 1 caractère, c'était pour caricaturer mon cas. Et l'antislash N n'a aucun raport avec recv Oo, c'est au niveau du code qu'il faut gérer ca, je peut très bien recevoir n'importe quoi ne se terminant pas par \n et juste après le recevoir.

    Mon code "entier" est comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
     
    int getplace(struct pollfd *poll_list, int *size, int *maxfd)
    {
    	int i;
    	for (i = 0; i < *size; i++) {
    		if (poll_list[i].fd == -1 || poll_list[i].fd == 0) {
    			if (i > *maxfd) {
    				*maxfd = i;
    			}
    			return i;
    		}
    	}
    	*size = *size*2;
    	realloc(poll_list, *size);
     
    	if ((i+1) > *maxfd) {
    		*maxfd = (i+1);
    	}
    	return (i+1);
    }
    int sockroutine() // Jai galéré pour cette fonction, help :(
    {
    	int basemem = 1024, maxfd = 0, attributed;
     
    	struct pollfd *poll_list = (struct pollfd *) malloc(1+sizeof(struct pollfd)*basemem);
    	int s_listen, new_fd, old_flags, verif, sin_size = sizeof(struct sockaddr_in), i;
    	struct sockaddr_in their_addr;
    	char *pSock = (char*)malloc(1+sizeof(char)*MAX_IO);
     
    	if ((s_listen = newSockListen(PORT)) < 0)
    	{
    		return 0;
    	}
    	old_flags = fcntl(s_listen, F_GETFL, 0);		// On récupère l'ancien bitmask
    	fcntl(s_listen, F_SETFL, old_flags | O_NONBLOCK); // Et on lui ajoute le non bloquant = SOCKET non Bloquant
     
    	attributed = getplace(poll_list, &basemem, &maxfd);
    	poll_list[attributed].fd = s_listen;
    	poll_list[attributed].events = POLLIN | POLLPRI;	
     
    	while(1) {
    			while (1) {
    				verif = poll(poll_list, maxfd+1, -1);
    				if (verif < 0) {
    					continue;
    				}
    				for (i = 0; i <= maxfd; i++) {
    					if (poll_list[i].fd == -1) {
    						continue;
    					}
    					if (poll_list[i].revents & (POLLIN)) {
    						if (poll_list[i].fd == s_listen) {
     
     
    							if ((new_fd = accept(s_listen, (struct sockaddr *)&their_addr, (unsigned int *)&sin_size)) > 0) {
    								old_flags = fcntl(new_fd, F_GETFL, 0);		// On récupère l'ancien bitmask
    								fcntl(new_fd, F_SETFL, old_flags | O_NONBLOCK); // Et on lui ajoute le non bloquant = SOCKET non Bloquant
     
    								attributed = getplace(poll_list, &basemem, &maxfd);
     
    								poll_list[attributed].fd = new_fd;
    								poll_list[attributed].events = POLLIN | POLLPRI;
     
    							//	sendSock(new_fd, HEADER);
     
    							//	close(new_fd);
    							//	poll_list[attributed].fd = -1;
    							}
     
     
    						}
    						else {
    							if (recv(poll_list[i].fd, pSock, MAX_IO, 0) < 1) {
    								if (poll_list[i].fd != s_listen) {
    									poll_list[i].fd = -1;
    								}
    							} else {
    								// traitement de pSock
    								printf("recu de %i\n", poll_list[i].fd);
    							}
    						}
    					}
    				}
    			}
    		}
     
    	return 0;
    }

  4. #4
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    Quelques remarques sur le style : on ne caste pas les malloc, on vérifie que les mallocs ne retournent pas NULL, et on utilise proprement realloc ( voir FAQ ).

    Quand à la question, il faudrait définir ce que tu appelle finir pour recv. Recv va finir, cad il va récuperer un octet dans ton buffer socket et l'ecrire dans ton buffer a toi. toutefois, je pense que tu ne pensais pas à ca quand tu parlais de finir. Si tu voulais dire : lire tout ce qui est disponible dans le buffer de la socket, non ce code ne fonctionne pas a priori. tu lis un octet dans chaque socket ou il y'a des choses a lire , puis tu apeplle poll a nouveau, et on recommence ...

    Tips : pour savoir combien d'octet a lire il y'a dans la socket, tu peux utiliser ioctl avec la commande FIONREAD : ce n'est toutefois pas extermemnt portable. Tu peux aussi utiliser un buffer statique plus grand que la taille max des données que tu envoie ou ce genre de chose

  5. #5
    Membre éclairé Avatar de |PaRa-BoL
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    738
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 738
    Points : 876
    Points
    876
    Par défaut
    Zul, merci pour tes remarques :

    Voici pour realloc et malloc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    poll_list = realloc(poll_list, *size);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct pollfd *poll_list = malloc(sizeof(*poll_list) * basemem);
    Mon code est il mieux ainsi ?

    Faut il que je garde le "1+" avant le sizeof ?

    Merci

  6. #6
    zul
    zul est déconnecté
    Membre éclairé Avatar de zul
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    498
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 498
    Points : 699
    Points
    699
    Par défaut
    Il me semblait que la faq indiquait la manière d'utiliser correctement realloc mais il ne semble pas que ca soit le cas. Il faudrait faire comme indiqué dans la faq de fr.comp.lang.c ( http://www.usenet-fr.net/fur/comp/lang/faq-c-3.html question 12.10 ).

    Pour le +1 , je ne pense pas, mais je n'ai pas bien regardé le code . Attention au parenthésage par contre . Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *pSock = (char*)malloc(1+sizeof(char)*MAX_IO);
    devrait etre ( enfin si j'ai bien compris ).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char * pSock = malloc((MAX_IO+1)*sizeof(char));
    Le fait que sizeof(char) renvoie 1 par définition fait que le code est correct mais l'ecriture en soit est incorrecte. On alloue ( truc + 1) case pas truc case + 1espace mémoire. La sémantique de calloc est peut-etre plus claire pour exprimer cela.

Discussions similaires

  1. [winsock.h] Fonction recv() pour un socket en C
    Par Hikaru dans le forum Windows
    Réponses: 5
    Dernier message: 22/05/2004, 07h43
  2. recv() et nombre d'octets lus...
    Par Gogoye dans le forum Réseau
    Réponses: 5
    Dernier message: 02/12/2003, 14h37
  3. [SOCKET C] deux send() pour un recv()
    Par trois_1 dans le forum Développement
    Réponses: 4
    Dernier message: 01/12/2003, 19h13
  4. fonction recv()
    Par billyboy dans le forum Développement
    Réponses: 2
    Dernier message: 04/10/2003, 17h52
  5. Les serveur proxy socks
    Par berry dans le forum Réseau
    Réponses: 6
    Dernier message: 26/01/2003, 17h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo