Page 1 sur 2

ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 20:07
par cowpowah
Salut à tous,

Code : Tout sélectionner

Size = ReceiveNetworkData(connection, *netBuffer, 65536)   
netBuffer.s = PeekS(*netBuffer, -1, #PB_UTF8)
J'ai un caratère #NULL dans *netBuffer, du coup PeekS() s’arrête avant la fin de la chaine.

Je trouve pas la solution là... :( (à part une boucle avec un PeekA(), ce que je voudrai éviter autant que possible)

A l'aide! :mrgreen:

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 20:21
par case
pour envoyer des chaines de caracteres il vaut mieux utiliser SendNetworkString() comme ca pas de #null
SendNetworkString() fournit une solution rapide pour envoyer rapidement des chaînes de caractères.
La chaîne sera envoyée en tant que donnée brute (sans le caractère NULL de terminaison), aussi peut-elle être reçue en utilisant ReceiveNetworkData(), après que NetworkServerEvent() / NetworkClientEvent() ait renvoyé #PB_NetworkEvent_Data).
En mode unicode la chaîne est envoyée en UTF-8, qui est indépendant du processeur (contrairement à UTF-16).

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 20:36
par cowpowah
Bein... C'est en réception là... :wink:

Et c'est au niveau du protocole websocket, donc pas le choix faut faire avec :|

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 22:01
par GallyHC
Bonjour,

Avez-vous juste essayé avec un simple PeekS(*netBuffer) ou même PeekS(*netBuffer, MemorySize(*netBuffer), #PB_Ascii), j'ai un doute sur l'utilisation de la constante "#PB_UTF8".

Cordialement,
GallyHC

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 23:35
par boby

Code : Tout sélectionner

Size = ReceiveNetworkData(connection, *netBuffer, 65536)  
Donc c'est toi via un autre programme qui envoie la string en question, et si... Tu donnais la taille de ta string que tu envois en entête comme tu lors de ton peekS tu pourras lui spécifier la taille à lire et ho magie on s'en cogne du caractére fin de string !!!

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : jeu. 27/déc./2018 23:51
par cowpowah
@GallyHC

C'est du Ascii, donc ascii ou UTF-8 ça passe, mais unicode (ou rien = unicode par défaut) ça me donne des caractères chinois... :?
Enfin quand je dis ça passe... Ça passe pas justement! :mrgreen:

@Boby
Non, ce n'est pas moi qui envois coté serveur, c'est l'API d'un site web via le protocol websocket. Mais il y a effectivement la taille du payload, en fait c'est justement là que sont les caractères NULL. Je vais essayer ta méthode... :wink:

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : ven. 28/déc./2018 13:00
par boby
l'UTF-8 a des taille de caractères variable, (1 à 2 bytes) l'unicode c'est fixé à 2 bytes, en effet si tu reçois de l'UTF-8 et que tu le lie en unicode, il t'arrivera de lire 2 caractères en même temps... D'où ton chinois.
Si tu n'as pas toutes les infos via l'API de ton site, une méthode un peut bourine utilisable consiste à writedata ton buffer dans un fichier histoir d'avoir une vague idée de la constitution des packets que tu reçois, une fois que tu as identifié ta string, tu peux tenter de peekI / A /... un peut au pife pour tenter de trouver où que c'est qu'ils stockent la taille de ta string, mais si l'API de ton site web est à ce point mal documenté... C'est pas forcément bon signe pour la suite des évènements :-/

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : ven. 28/déc./2018 13:43
par Marc56
boby a écrit :l'UTF-8 a des taille de caractères variable, (1 à 2 bytes) [...]
Et même un peu plus: 1 à 4 octets.

Réf.

:wink:

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : ven. 28/déc./2018 21:33
par cowpowah
Hello :)

Bon ça fonctionne en prenant la string après le caractère NULL (avec un peu de bricolage pour trouver le bon endroit) comme tu as dis, boby, merci! :wink:

Code : Tout sélectionner

netBuffer.s = PeekS(*netBuffer+skip, -1, #PB_UTF8)
par contre il m'arrive un truc bizarre: le message est envoyé en plusieurs morceaux, et au moment de les assembler il me manque un caractère... le dernier de chaque morceau, sauf du dernier :?

C'est un problème de connu de ReceiveNetworkData() ou de PeekS()? Ou ça vient plutôt du serveur?

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : ven. 28/déc./2018 23:04
par djes
Tu as la taille de la chaîne reçue, du coup il faut l'utiliser et pas utiliser -1.

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : sam. 29/déc./2018 0:06
par cowpowah
Ça donne le même résultat, à la fin de chaque bloc j'ai un retour à la ligne et ce caractère: � ("replacement character" en unicode, parait-il...)

EDIT: oubliez ça... Une erreur à la c... :mrgreen: Ma faute :oops:

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : sam. 29/déc./2018 19:18
par cowpowah
Bah en fait si...

ReceiveNetworkData() me fait un truc bizarre: quand je dois recevoir des frames assez grandes (variable, mais 20/30Ko minimum en général), je les reçois en plusieurs fois.

par exemple pour 1 frame de 80Ko:

Code : Tout sélectionner

Case #PB_NetworkEvent_Data

Repeat
Size = ReceiveNetworkData(connection, *netBuffer, 65536)
;##code quand le buffer est plein##
Until Size <> 65536
Il va passer 4 fois par #PB_NetworkEvent_Data (4 x 20Ko, taille variable mais total=80Ko), plutôt que remplir le buffer de ReceiveNetworkData() (65+15Ko). Il rempli jamais le buffer :?

Et à chaque 'coupure' il ajoute des caractères à la fin du bloc: 1 saut de ligne, 1 �, 1 autre saut de ligne. Je dois faire un

Code : Tout sélectionner

payload.s = Left(payload.s, Len(payload.s)-3)            ; removing ReceiveNetworkData() garbage at EOL (only when ReceiveNetworkData() splits data)
après chaque bloc.

Par contre une frame de 5/10Ko, aucun soucis!

C'est normal? Ou c'est parce que j'utilise Stunnel?

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : sam. 29/déc./2018 20:20
par Ollivier

Code : Tout sélectionner

Structure Buffer
   A.A[65536]
EndStructure

Define *Mem.Buffer
Ça, c'est un gabarit mémoire. Je corrigerai la structure, mais il me semble que ça considère 65 536 octets précisément.

Ici << Define >> n'alloue rien ou presque rien (la taille d'une variable de pointage).

Donc si j'alloue un tampon mémoire quelconque :

Code : Tout sélectionner

Define *X = AllocateMemory(1000)
Quand je positionne mon gabarit sur ce tampon comme ça :

Code : Tout sélectionner

*Mem = *X
je peux lire/écrire à la volée tout ce qui est dans cette zone mémoire.

Je fais attention car *Mem\A[1001] est peut-être dans le gabarit. Mais le gabarit n'a rien à voir avec la mémoire allouée, donc *Mem\A[1001] provoque une erreur IMA.

On se sert de MemorySize() pour éviter ça, mais MemorySize() c'est quand on a alloué soit-même, avec AllocateMemory().

Là, ce n'est pas AllocateMemory() mais ReceiveNetworkData(). Je doute fort qu'il n'aie pas une quantité exacte d'octets fournie avec.

Les paquets que tu reçois c'est normal : ça dépend du temps qu'il fait, du trafic et de l'affluence sur le serveur.

Des fois, les paquets sont petits, des fois, carrément pas.
Un gabarit de 64 mégas me semble éviter la contre-euphorie du << C'est génial : mon appli crashe tellement ton réseau il est bon ! >>

Et je rappelle bien que ce gabarit n'alloue rien : c'est juste un repérage de compilation.

Grâce à lui, si une chaîne standard à zéro terminal est coupée en 18, zéro ou pas tu pourras tout lire. Tout analyser, ce qui est le but de la manoeuvre...

En espérant éclairer ta lanterne...

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : dim. 30/déc./2018 6:00
par cowpowah
Ollivier a écrit :Les paquets que tu reçois c'est normal : ça dépend du temps qu'il fait, du trafic et de l'affluence sur le serveur.

Des fois, les paquets sont petits, des fois, carrément pas.
D'accord! Donc en fait, c'est le serveur qui découpe la frame et rajoute des caractères de fin de paquet et non PureBasic?

Je pensais que les paquets étaient réassemblés avant le #PB_NetworkEvent_Data, que c'était géré au niveau du protocole TCP.

Re: ReceiveNetworkData(), PeekS() et caractère #NULL

Publié : dim. 30/déc./2018 19:18
par djes
C'est un des principes de base du protocole ip. Tout est découpé en paquets qui vont emprunter différents chemins pour arriver à destination. TCP va s'occuper de tout recoller. La taille du buffer de réception n'a rien à voir avec la taille du fichier envoyé, c'est juste un espace mémoire suffisamment grand pour accueillir un ou plusieurs paquets (max 65536 en tcp). C'est à toi d'interpréter les paquets rentrants pour savoir ce que tu vas recevoir et gérer tout ça, notamment la taille du buffer final qui peut être plus grand que le buffer de réception.

j'avais fait un petit exemple complet client/serveur, voir ici : https://www.purebasic.fr/french/viewtop ... =6&t=16493

Ca peut servir aussi à observer un autre serveur, il suffit de changer une ligne de code...