Empêcher des réceptions de s'agglomérer (et autres questions...)

FlorimondH Messages postés 11 Date d'inscription lundi 24 septembre 2007 Statut Membre Dernière intervention 13 mars 2010 - 11 sept. 2008 à 22:44
FlorimondH Messages postés 11 Date d'inscription lundi 24 septembre 2007 Statut Membre Dernière intervention 13 mars 2010 - 12 sept. 2008 à 17:27
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 9" />
<meta name="Originator" content="Microsoft Word 9" />
<link rel="File-List" href="file:///C:/DOCUME%7E1/FHU/LOCALS%7E1/Temp/msoclip1/01/clip_filelist.xml" />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:"DejaVu Sans";
panose-1:2 11 6 3 3 8 4 2 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-419414273 -771688961 41 0 511 0;}
@font-face
{font-family:"Nimbus Sans L";
mso-font-alt:Arial;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
{margin-top:6.0pt;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan no-line-numbers;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;
font-style:italic;}
p.MsoList, li.MsoList, div.MsoList
{mso-style-parent:"Corps de texte";
margin-top:0cm;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.MsoTitle, li.MsoTitle, div.MsoTitle
{mso-style-next:"Corps de texte";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-hyphenate:none;
font-size:14.0pt;
font-family:"Nimbus Sans L";
mso-fareast-font-family:"DejaVu Sans";
mso-bidi-font-family:"DejaVu Sans";
mso-fareast-language:AR-SA;}
p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
{margin-top:0cm;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.Rpertoire, li.Rpertoire, div.Rpertoire
{mso-style-name:Répertoire;
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan no-line-numbers;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
@page Section1
{size:595.25pt 841.85pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>

Bonjour à tous,





 C'est la première fois
que je tente l'aventure avec Winsock et il s'avère que ce n'est pas une si
mince affaire que je ne l'imaginais. J'ai lu plusieurs petits tutoriaux sur le
sujets mais aucun ne parlais de mon problème principal. A côté de celui-ci j'ai
plusieurs questions requérant vos conseils avisés.





1) Mis à part un tableau
booléen à 2 dimensions à envoyer dès que la connection est établie, j'ai
principalement 2 types de données à envoyer quelque soit le moment. Il peut
s'agir de texte que les correspondants s'échangent, ou alors c'est un numéro
d'index qui dépend de l'endroit dans lequel un des deux correspondants a
cliqué. Ma première intuition fut de considérer tout envoi comme étant du
format String, en ajoutant un caractère devant chaque envoi pour signifier de
quoi il s'agit (1 pour l'index et 2 pour du texte). Si c'est du texte j'extrais
simplement le reste de la chaine que j'affiche dans un text box sans autre
traitement. Si c'est un index je l'utilise en argument après une transformation
par val(). Rien de plus simple à priori. Peut-être pas très « pro »,
j'attends vos suggestions...





 Seulement déjà là j'ai
rencontré un problème: si on clique trop vite tous les index sont envoyés dans
le même paquet, ce qui pose un problème lors de la réception à mon petit
système très basique. J'ai vu quelque part Jack parler de « réceptions
agglomérées » et de « réceptions tronçonnées » sans donner plus
d'explications. Le problème est particulièrement flagrant quand j'envoie le
tableau puisque je l'envoie case par case dans une boucle (ayant lu que
l'envoyer d'un coup, brute, ne fonctionne pas) et tout arrive dans le même
paquet. Il me semble donc qu'il doivent s'agir de « réception
agglomérée » (ben oui connais pas moi, pas encore...). Pour résoudre le
problème j'ai bien sûr pensé à mettre dans l’en-tête de chaque envoi, après le
chiffre indiquant le type de donnée, une autre une zone de 4 caractères
indiquant le nombre de caractères que fait le contenu lui même afin de
déterminer la limite de chaque envoi (je ne sais pas si je me fais bien
comprendre). Est-ce la meilleure solution? En y réfléchissant il me semble que
des envois agglomérés pourraient aboutir, à la limite, à des envois tronçonnés
car les données envoyées en même temps, trop nombreuses, seraient coupées
n'importe où -> et re bug! De plus ce système rendrait plus compliqué la
gestion des accusés de réception.





 Donc, n'y a-t-il pas
un moyen de simplement empêcher les envois de s'agglomérer? Aurait-on
exactement le même soucis en UDP ?…






<!--[if !supportEmptyParas]--> <!--[endif]-->





Bon voilà je me rend compte
que c'est déjà long alors je poserai mes autres question plus tard, si je
pouvais déjà résoudre ce problème je serais loin!





Merci
à ceux qui auront le courage de tout lire…

4 réponses

PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
12 sept. 2008 à 04:44
Salut,

même problème en UDP = > pire même, car UDP travaille sans "accusé de réception", donc un paquet perdu est vraiment perdu...
TCP
va quand même vérifier chaque paquet et le redemander si nécessaire (en
transparence, tu n'as pas d'évènement winsock pour t'en assurer)

utiliser tes Data uniquement en string est suffisant. peut-être un peu coûteux pour tes tableaux etc... mais çà fonctionnera

il y a juste 2 points à comprendre :

* un
paquet envoyé/reçu a une taille MAX fixe (selon la config du PC), mais
pas MIN. de ce fait tu envoies "bonjour", je peux recevoir tant
"bonjour" que "bon" puis "jour"

*le winsock travaille
comme une file d'attente. s'il a un message à envoyer et que tu lui en
donnes un second, il peut très bien les fusionner en 1 (ou plusieurs)
envoi

=> taille MIN : il suffit de forcer la séparation de chaque message, par une chaîne perso.
par
exemple tous tes envois doivent se finir par "#MON_SéPARATEUR#"
(conseillé évidemment de mettre un caractère non produisible au
clavier, comme  CHR(0). néanmoins pour un risque d'erreur, faudrait
vraiment que la chaîne soit coupée pile à cet endroit )
ensuite côté réception, tu stoques la valeur reçu en boucle jusqu'à ce que la fin du message soit le séparateur

= > fusion : pour forcer l'envoi séparé, un simple doevents suffit.

en gros çà te donne un procédure perso....
au lieu de winsock1.senddata "2machaine", tu appelles :

sub SendData(byval iIndice as integer, byval sData as string)
  if winsock1.state = sckconnected '<- à vérifier, vaut 7
    winsock1.senddata cstr(iindice) & sdata & "$$?SEP?$$" & vbnullchar
    doevents
  endif
end sub

et côté réception, du genre
private sub winsock1_dataarrival(je_sais_plus)
  static sBuffer as string
  sbuffer =

sbuffer &


winsock1.getdata '(ou argument, pas le courage de vérifier )
  if right$(sbuffer,len(SEPAR)) = SEPAR then
     'tu fais tes bricoles en enlevant la fin
     'ET tu n'oublies surtout pas de vider ton tampon !!!
     sbuffer=vbnullstring
  'ELSE rien à faire, la suite va arriver au prochain évènement
endif
end sub





voilà en gros le principe et les méthodes à appliquer, j'espère que c'est un peu plus clair

bonne soirée
PCPT [AFCK]

<hr size="2" width="100%" />
Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
FlorimondH Messages postés 11 Date d'inscription lundi 24 septembre 2007 Statut Membre Dernière intervention 13 mars 2010
12 sept. 2008 à 14:15
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="ProgId" content="Word.Document" />
<meta name="Generator" content="Microsoft Word 9" />
<meta name="Originator" content="Microsoft Word 9" />
<link rel="File-List" href="file:///C:/DOCUME%7E1/FHU/LOCALS%7E1/Temp/msoclip1/01/clip_filelist.xml" />
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:HyphenationZone>21</w:HyphenationZone>
<w:DoNotOptimizeForBrowser/>
</w:WordDocument>
</xml><![endif]-->
<style>
<!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;
mso-font-charset:2;
mso-generic-font-family:auto;
mso-font-pitch:variable;
mso-font-signature:0 268435456 0 0 -2147483648 0;}
@font-face
{font-family:Tahoma;
panose-1:2 11 6 4 3 5 4 4 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:553679495 -2147483648 8 0 66047 0;}
@font-face
{font-family:"Nimbus Sans L";
mso-font-alt:Arial;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:0 0 0 0 0 0;}
@font-face
{font-family:"DejaVu Sans";
panose-1:2 11 6 3 3 8 4 2 2 4;
mso-font-charset:0;
mso-generic-font-family:swiss;
mso-font-pitch:variable;
mso-font-signature:-419414273 -771688961 41 0 511 0;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{mso-style-parent:"";
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.MsoCaption, li.MsoCaption, div.MsoCaption
{margin-top:6.0pt;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan no-line-numbers;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;
font-style:italic;}
p.MsoList, li.MsoList, div.MsoList
{mso-style-parent:"Corps de texte";
margin-top:0cm;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.MsoTitle, li.MsoTitle, div.MsoTitle
{mso-style-next:"Corps de texte";
margin-top:12.0pt;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
page-break-after:avoid;
mso-hyphenate:none;
font-size:14.0pt;
font-family:"Nimbus Sans L";
mso-fareast-font-family:"DejaVu Sans";
mso-bidi-font-family:"DejaVu Sans";
mso-fareast-language:AR-SA;}
p.MsoBodyText, li.MsoBodyText, div.MsoBodyText
{margin-top:0cm;
margin-right:0cm;
margin-bottom:6.0pt;
margin-left:0cm;
mso-pagination:widow-orphan;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
p.Rpertoire, li.Rpertoire, div.Rpertoire
{mso-style-name:Répertoire;
margin:0cm;
margin-bottom:.0001pt;
mso-pagination:widow-orphan no-line-numbers;
mso-hyphenate:none;
font-size:12.0pt;
font-family:"Times New Roman";
mso-fareast-font-family:"Times New Roman";
mso-fareast-language:AR-SA;}
@page Section1
{size:595.25pt 841.85pt;
margin:70.85pt 70.85pt 70.85pt 70.85pt;
mso-header-margin:36.0pt;
mso-footer-margin:36.0pt;
mso-paper-source:0;}
div.Section1
{page:Section1;}
-->
</style>

Merci
beaucoup pour ta réponse

:-)













J'aimerais revenir sur
quelques points avant la mise en œuvre.






<!--[if !supportEmptyParas]--> <!--[endif]-->





--« TCP
va quand même vérifier chaque paquet et le redemander si nécessaire (en
transparence, tu n'as pas d'évènement winsock pour t'en assurer) »






<!--[if !supportEmptyParas]--> <!--[endif]-->





Cela signifie-t-il que je
n’ai à m’occuper de rien de ce côté ? Je pensais à plusieurs choses. On
peut simplement renvoyer qu’on a reçu quelque chose. On peut renvoyer le nombre
d’octets qu’on a reçu (ben oui on pourrait imaginer que la somme de contrôle
ait été endommagée de telle sorte qu’elle montre bien le nombre d’octets reçus,
malgré le fait que l’envoi n’ait été reçu qu’en partie…bon, non c’est vrai
-> hautement improbable). A la rigueur on pourrait renvoyer exactement ce
qu’on a reçu pour que le client vérifie son identité par rapport à ce qu’il vient
effectivement d’envoyer. Au cas où c’est différent il le renvoie. Au bout de
deux boucles comme ça, on pourrait afficher un message de
« connection : bad » etc… Mais d’après ce que tu me dis, Winsock
gère tout ça de lui même ?! C’est plus que je n’en espérait !






<!--[if !supportEmptyParas]--> <!--[endif]-->





--« *un
paquet envoyé/reçu a une taille MAX fixe (selon la config du PC), mais pas MIN.
de ce fait tu envoies "bonjour", je peux recevoir tant
"bonjour" que "bon" puis "jour" »






<!--[if !supportEmptyParas]--> <!--[endif]-->





Bon, d’après ce que j’ai
compris, DoEvents empêche des envois différents de s’agglomérer. Tu me décrit
ensuite un système, avec un vbNullChar pour indiquer la fin des données au cas
où, l’envoi trop long, il serait tronçonné. Cependant, n’est-il pas possible de
produire tous les caractères de la table…je ne sais plus comment mais ça devait
être en maintenant la touche Alt enfoncée et tapant le code au clavier
numérique. « Null » n’étant pas un « caractère » il ne
s’afficherait pas mais le programme conserverait quand-même un code en interne.
Ce caractère Null pourrait être fait par erreur, d’autant plus si on a affaire
à un habitué des caractères spéciaux qui aime par exemple mettre des petites
notes de musiques dans son texte…bon d’accord, ça va loin mais quand on fait un
programme c’est ce qu’il faut…donc c’est pour ça que tu couple un caractère
« impossible » à produire au clavier à un séparateur
« texte » $$ ?SEP ?$$ pour être sûr.






<!--[if !supportEmptyParas]--> <!--[endif]-->






 winsock1.senddata
cstr(iindice) & sdata &
"$$?SEP?$$" & vbnullchar






<!--[if !supportEmptyParas]--> <!--[endif]-->





Est-ce que j’ai bien compris ?






<!--[if !supportEmptyParas]--> <!--[endif]-->





(D’autre part, on pourrait volontairement laisser le
contenu des cases du tableau s’agglomérer, ça serait moins lourd que de forcer
le programme à envoyer tout séparément…)
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
12 sept. 2008 à 14:40
TCP vérifie donc tu n'as pas à t'en soucier...
de plus çà pourrait très bien être "ton accusé de réception perso" qui serait endommagé, dans le cas de figure de ton explication ^^

DOEVENTS n'empêche pas "bonjour" de devenir "bon" et "jour", il empêche "message1" puis
"message2" de devenir
"message1
message2"








je ne t'ai donné qu'un exemple pour les "caractères séparateurs", à toi aussi de faire le code pour empêcher la saisie des caractères critiques si tu penses que l'utilisateur a pour seul but de réussir à ne pas utiliser un programme qu'il a besoin ^^. mais l'idée est bien là oui, un séparateur à chaque message

envoyer tout ton tableau séparé n'est pas forcément judicieux. çà ne veut pas dire que tu dois ou ne dois pas envoyer case par case, ou jouer des fois ou non avec doevents  (PUISQUE çà ne change pas le fait que les messages peuvent être coupés!), à toi de voir comment organiser ton envoi pour qu'il te soit possible de le récupérer....

si le but est d'envoyer... les coordonnées d'un plateau de bataille navale par exemple, il y a sans doute plus utile comme "paquet" que d'envoyer les références de chaque case

++

<hr size="2" width="100%" />
Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp
0
FlorimondH Messages postés 11 Date d'inscription lundi 24 septembre 2007 Statut Membre Dernière intervention 13 mars 2010
12 sept. 2008 à 17:27
--"TCP vérifie donc tu n'as pas à t'en soucier...
de
plus çà pourrait très bien être "ton accusé de réception perso" qui
serait endommagé, dans le cas de figure de ton explication ^^"

Tout à fait, d'où ça aboutirais sur une boucle "je t'envoie, c'est ça?, non c pas ça je te renvoie, bon alors c'est ça?, mais non je te dis que c'est ça!,..."



Il y a des chances, à condition que la connexion ne soit pas encore trop mauvaise, que qu'on sorte de cette boucle. Ca serait un moyen très lourd, certes, mais le plus sûr de savoir si on a bien reçu tout ce qu'on devait recevoir... mais je me pose sûrement beaucoup trop de questions...


--"DOEVENTS n'empêche pas "bonjour" de devenir "bon" et "jour", il empêche "message1" puis
"message2" de devenir
"message1
message2" "

oui oui ça pas de soucis j'avais bien compris ^^

--"je ne t'ai donné qu'un exemple pour les
"caractères séparateurs", à toi aussi de faire le code pour empêcher la
saisie des caractères critiques si tu penses que l'utilisateur a pour
seul but de réussir à ne pas utiliser un programme qu'il a besoin ^^."

ben j'ai remarqué que les gens arrivent toujours à ne pas faire les choses comme tu le voudrais et à tout planter! Mon idéal de qualité pour un programme c'est un programme qui consent à planter à partir du moment où tu a jeté le PC du 3ème étage...

--"envoyer tout ton tableau séparé n'est pas
forcément judicieux. çà ne veut pas dire que tu dois ou ne dois pas
envoyer case par case, ou jouer des fois ou non avec doevents  (PUISQUE
çà ne change pas le fait que les messages peuvent être coupés!), à toi
de voir comment organiser ton envoi pour qu'il te soit possible de le
récupérer....

si le but est d'envoyer... les coordonnées d'un
plateau de bataille navale par exemple, il y a sans doute plus utile
comme "paquet" que d'envoyer les références de chaque case"

ben dans ce cas...il faut quand même bien envoyer la disposition initiale du plateau. Il peut être généré puis envoyé, ou envoyé au fur et à mesure de sa génération. Dans ce dernier cas, la question ne se pose pas, forcément tu l'envoie case par case...tu pensais à quoi?
D'autre part, si, moi je pensais bel et bien à ne pas mettre de DoEvents dans la boucle qui envoie la tableau pour que finalement le  tableau soit envoyé en entier (ou presque) dans le même paquet... après ça peut être coupé en plusieurs paquets selon les fantaisies Winsock, du réseau, de la config de je ne sais quoi, mais en tout cas ça sera toujours plus rapide que de faire 1 paquet par case...
0
Rejoignez-nous