Buffer winsock

Résolu
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008 - 30 déc. 2005 à 13:51
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008 - 1 janv. 2006 à 04:22
Bonjour,
je suis entrain de developper un eaplication utilisant winsock sous windows avec Dev-c++.
Je voudrais connaitre la taille de la file d'attente du sock pour pouvoir récuperer tout son contenu en 1 seule fois avec RECV.
Merci d'avance et bonne année.

16 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 déc. 2005 à 19:43
Salut,

Ecrire 'je comprend rien' en gros c'est pas ca qui debuguera ton programme.

Regardes ce que tu fais: recv(sock, NULL, length, MSG_PEEK); tu ne
passes meme pas l'adresse du buffer, pas etonnant que ca plante..

Aussi dans ton code, le free ne sert a rien puisque la variable buff n'a pas été alouée avec malloc.



Moi j'aurais fait un truc de ce genre (à tester):





char buffer[2000];


int r;





r = recv(sock, buffer, 2000, MSG_PEEK); // on lis les données

while(r > 0 && buffer[r] != '|')
r--;
// trouve le dernier | dans le buffer

if(r > 0)

{

recv(sock, buffer, r, 0);

// ici buffer contient des commandes completes terminées par |.

}



Je ne suis pas chez moi donc je ne peux pas tester (compiler) ton code
ou mon exemple pour voir si ca marche vraiment, donc c'est a prendre
avec des pincettes.
3
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
1 janv. 2006 à 04:18
J'ai trouvé c'est bon lol, chuis pas radin vais en faire profiter tout le monde

char buf[4096];

i recv(sock, buf, sizeof(buf), MSG_PEEK); buf[i] 0;
if(strlen(buf) && i && numchars(buf, '¦'))
{
if(strlen(buf) == i) while(buf[i] != '¦' && i > 0) i--; buf[0] = 0;
i recv(sock, buf, i+1, 0); buf[i] 0;
}
else return;

[
nomchars c 1 fonction que j'ai fait qui me retourne le nonbre d'instances du caractere passé en second parametres dans un char*.
]

voila, lol sa marche, merci a vous tous pour vos réponses, vos pseudos figureront dans mon about. A+ tlm et bonne année 2006 !!!
3
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
30 déc. 2005 à 14:30
Pourquoi ne pas le récupérer en plusieurs fois ou est le problème ?

Shell
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 14:33
bein en fait, j'envoie des commandes a trevers winsock, a la fin de chaque commande j'ai un caractere de séparation mais, lorsque je recois beaucoup de commandes, le buffer ne peut pas tout récupérer et la dernière commande se retrouve coupée en 2.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
30 déc. 2005 à 14:37
Je vois toujours pas ou est le problème ???

Shell
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 14:41
bon, jvais essayer d'etre lpus clair :

on m'envoir par exemple :
>>commande1|
>>commande2|
>>commande3|
(| = char de separation)

je recois :
<<commande1|commande2|comm
<<ande3|
car mon buffer est trop petit et ma derniere comande est couper.
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 14:44
j'aimerais donc savoir comment connaitre la taille de la file d'attente pour tout recuperer.
J'avais essayé autrement :

char tmpwait[2005];


void sckread()
{
char *cmd, buf[4015];
unsigned int len;
if(strlen(tmpwait))
{
char buff[2005];
len = recv(sock, buff, 2000, 0);
buff[len] = '\0';
strcpy(buf, tmpwait);
strcat(buf, buff);
tmpwait[0] = '\0';
GlobalFree(&tmpwait);
}
else
{
len = recv(sock, buf, 2000, 0);
buf[len] = '\0';
}
if(strcmp(mid(buf, strlen(buf)-1, strlen(buf)), "¦"))
{
i = strlen(buf); while(buf[i] != '¦') i--;
strcpy(tmpwait, mid(buf, i+1, strlen(buf)));
char tmptobuf[2005];
strcpy(tmptobuf, mid(buf, 0, i+1));
strcpy(buf, tmptobuf);
pckovr ++;
}


// ...

}

le principe c'était de conserver la 1ere partie de la commande coupée et d'attendre la 2eme pour la recoller mais bizarrement, a la fin, il me manque des commandes.
0
DeAtHCrAsH Messages postés 2670 Date d'inscription vendredi 25 janvier 2002 Statut Membre Dernière intervention 6 février 2013
30 déc. 2005 à 14:47
Dans ce cas la ne prend en compte que les commandes completes c'est a dire celle qui se termine par |
Celle qui est incomplete bufferise la dans une variable globale, et lors de la prochaine récéption du socket tu pourras la completer.

Une autre solution est de bouclé sur le recv tant qu'il y a des cotets a lire.

Shell
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 15:48
et comment je sais s'il y a des octets a lire?
j'ai essayé

len = 1
while (len)
len = recv(...)

sa marche pas

PS : si ce mess aparait en quadruple je pete 1 plon
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
30 déc. 2005 à 17:07
Salut,

Tu peux avoir la taille du buffer de reception d'un socket avec getsockopt() et le flag SO_RCVBUF.

Cependant ca ne resoudra pas ton probleme, le principe de ton algo est
bon donc c'est plutot lui qu'il faudrait chercher à travailler.



Sinon il y a une autre idée, c'est d'utiliser recv() avec le flag
MSG_PEEK. Utilisé avec ce flag, recv() va lire les données du buffer de
reception SANS les suprimer, donc ca te permet de calculer combien de
commandes complete tu as recues, et donc de determiner combien d'octet
tu dois lire afin de ne pas lire de 'morceaux' de commandes. Lorsque tu
as calculé cette valeur, un recv() sans MSG_PEEK enlevera les
octets des commandes completes et ne laissera que les morceaux
incomplets dans le buffer (qui seront completés par la suite).
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 18:37
ok mais jvois pas le probleme :s

char buf[4015];
unsigned int len;

if(strlen(tmpwait))
{
char buff[2005];
len = recv(sock, buff, 2000, 0);
buff[len] = 0;
strcpy(buf, tmpwait);
strcat(buf, buff);
free(buff);
}
else
{
len = recv(sock, buf, 2000, 0);
buf[len] = 0;
}
if(strcmp(mid(buf, strlen(buf)-1, strlen(buf)), "¦"))
{
i = strlen(buf); while(buf[i] != '¦') i--;
strcpy(tmpwait, mid(buf, i+1, strlen(buf)));
strcpy(buf, mid(buf, 0, i+1));
}

ca devrait marcher :s mais sa marche pas, je perd beaucoup de commandes.

Quelqu'un pourrait-il m'expliquer pourquoi sa marche pas SVP ???

Pour le msgpeek, je comptais faire ca :

unsigned int len, length = 2000;
bool receiving = true;
while (receiving)
{
len = recv(sock, NULL, length, MSG_PEEK);
if(len < length)
{
receiving = false;
length = len;
}
else length += 2000;
}
char buf[length]; len recv(sock, buf, length, 0); buf[len] 0;

mais ca crash....

JE COMPRENDS RIEN, SA DEVRAIT MARCHER :(
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
30 déc. 2005 à 19:52
ok, merci je vais tester. Pour ce qui est du NULL, sa plante tt autan qu'avec un buffer.
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
31 déc. 2005 à 00:10
J'ai essayé ce que tu m'as dis, aardman, sa crash le prog, j'ai essayé lpusieurs possibilités de cette méthode et j'en suis arrivé a ceci :

char buf[2000]; int i;
i = recv(sock, buf, sizeof(buf), MSG_PEEK);
if(i == sizeof(buf))
while(buf[i] != '¦') i--;
recv(sock, buf, i, 0); buf[i] = '\0';

en théorie, sa marche, mais en pratique, sa fonctionne 1 ou de fois puis le prog se ferme sans message d'erreur.
0
n_o_u_n_o_u Messages postés 14 Date d'inscription lundi 23 février 2004 Statut Membre Dernière intervention 14 février 2006
31 déc. 2005 à 00:32
Bonsoir,


pourquoi ne pas transférer ce que tu reçois du winsock dans une variable à côté de ton buffer de réception.
Cette variable te servirait à concaténer les informations reçues par ton contrôle winsock afin de reconstruire les informations
intéressantes pour ton programme : ces informaitons serait encadrées par une base de début et une balise de fin et par conséquent facilement exploitables. Après, cela dépend du protocole que tu utilises (UDP ou TCP)...

Qu'en penses tu ?
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
31 déc. 2005 à 01:04
Salut,

Un prog qui "crash sans afficher de message d'erreur" c'est impossible
a debuguer. C'est a toi d'afficher les erreurs et le contenu de tes
variables afin d'etre capable, lors de l'execution du programme, de
bien visualiser ce que le code fait, et ce qu'il fait mal.
0
unrealgun Messages postés 87 Date d'inscription mardi 16 décembre 2003 Statut Membre Dernière intervention 4 mars 2008
1 janv. 2006 à 04:22
.. petite dernière remarque, a la création de mon socket, j'ai allongé la file d'attente pour etre sur de ne pas perdre de commandes :

{
char *option = "100000";
setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&option, strlen(option));
}
0
Rejoignez-nous