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

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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:
Avatar de l’utilisateur
case
Messages : 1528
Inscription : lun. 10/sept./2007 11:13

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

Message 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).
ImageImage
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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 :|
Avatar de l’utilisateur
GallyHC
Messages : 1703
Inscription : lun. 17/déc./2007 12:44

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

Message 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
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

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

Message 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 !!!
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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:
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

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

Message 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 :-/
Marc56
Messages : 2147
Inscription : sam. 08/févr./2014 15:19

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

Message 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:
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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?
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

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

Message par djes »

Tu as la taille de la chaîne reçue, du coup il faut l'utiliser et pas utiliser -1.
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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:
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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?
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

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

Message 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...
cowpowah
Messages : 41
Inscription : mer. 02/juin/2010 12:41

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

Message 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.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

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

Message 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...
Répondre