Page 1 sur 1
Communication Client Serveur
Publié : dim. 18/sept./2016 22:28
par falsam
Lorsque qu'on envoie des données à un serveur avec la commande SendNetworkString(), le buffer de réception peut soit contenir un seul SendNetworkString() ou plusieurs à la suite sans aucune séparation.
De-concaténer une telle chaîne n'est pas pratique.
J'ai quelques questions :
- Quelle serait la bonne taille du buffer de réception utilisé par la commande ReceiveNetworkData() ?
- J'ai des idées pour concaténer la chaîne envoyée par le
client mais vous quelle méthode vous utilisez ?
Vous trouverez un exemple de serveur simplifié ainsi qu'un client simplifié envoyant plusieurs données au serveur avant de se déconnecter.
■
server.pbCode : Tout sélectionner
If InitNetwork() = 0
Debug "Server - Can't initialize the network !"
End
EndIf
Port = 6832
*Buffer = AllocateMemory(1000)
If CreateNetworkServer(0, Port)
Debug "Server - Server created (Port "+Str(Port)+")."
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "Server - A new client has connected !"
Case #PB_NetworkEvent_Data
Debug "Server - Client "+Str(ClientID)+" has send a packet !"
FreeMemory(*Buffer)
*Buffer = AllocateMemory(1000)
ReceiveNetworkData(ClientID, *Buffer, 1000)
Debug "Server - *Buffer: "+PeekS(*Buffer, -1, #PB_UTF8)
Case #PB_NetworkEvent_Disconnect
Debug "Server - Client " + Str(ClientID)+" has closed the connection..."
EndSelect
EndIf
ForEver
CloseNetworkServer(0)
Else
Debug "Server - Can't create the server (port in use ?)."
EndIf
■
Client.pbCode : Tout sélectionner
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
Debug "Client - Connected To server..."
Debug "Client - A string has been sent To the server ..."
For i = 0 To 10
SendNetworkString(ConnectionID, "Event 1 - " + i, #PB_UTF8)
SendNetworkString(ConnectionID, "Event 2 - " + i, #PB_UTF8)
Next
CloseNetworkConnection(ConnectionID)
Else
Debug "Client - Oops ! Can't find the server (Is it launched ?)."
EndIf
Regarder le résultat reçu par la commande dans la ligne
ReceiveNetworkData(ClientID, *Buffer, 1000) du serveur.
Parfois il reçoit un seul évenement envoyé par le client et parfois il en reçoit plusieurs à la suite sans aucun caractère de séparation.
Debug a écrit :Server - A new client has connected !
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 0Event B - 0
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 1
Server - Client 37358352 has send a packet !
Server - *Buffer: Event B - 1
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 2
Server - Client 37358352 has send a packet !
Server - *Buffer: Event B - 2
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 3
Server - Client 37358352 has send a packet !
Server - *Buffer: Event B - 3
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 4
Server - Client 37358352 has send a packet !
Server - *Buffer: Event B - 4
Server - Client 37358352 has send a packet !
Server - *Buffer: Event A - 5
Server - Client 37358352 has send a packet !
Server - *Buffer: Event B - 5Event A - 6Event B - 6Event A - 7Event B - 7Event A - 8Event B - 8Event A - 9Event B - 9Event A - 10Event B - 10
Server - Client 37358352 has closed the connection...
Merci d'avance pour vos réponses.
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 8:14
par Zorro
voila comment je ferai :
Serveur :
Code : Tout sélectionner
If InitNetwork() = 0
Debug "Server - Can't initialize the network !"
End
EndIf
Port = 6832
*Buffer = AllocateMemory(1000)
If CreateNetworkServer(0, Port)
Debug "Server - Server created (Port "+Str(Port)+")."
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "Server - A new client has connected !"
Case #PB_NetworkEvent_Data
Debug "Server - Client "+Str(ClientID)+" has send a packet !"
*Buffer = AllocateMemory(1024)
ReceiveNetworkData(ClientID, *Buffer, 1024) ; reçois la taille du message
taille=Val(stringfield(PeekS(*Buffer,-1, #PB_UTF8),1,";"))
nbr_phrase=Val(stringfield(PeekS(*Buffer,-1, #PB_UTF8),2,";"))
if Taille>0
*Buffer2 = AllocateMemory(taille)
ReceiveNetworkData(ClientID, *Buffer2,taille)
complete_message.s=PeekS(*Buffer, -1, #PB_UTF8)
Debug "Server - *Buffer: "+complete_message.s
For i=3 to nbr_phrase ; on saute les 2 informations de debut qui indique la taille en caracteres d message , et le nombre de phrase
debug stringfield(complete_message.s,i,";")
Next i
Endif
Case #PB_NetworkEvent_Disconnect
Debug "Server - Client " + Str(ClientID)+" has closed the connection..."
EndSelect
EndIf
ForEver
CloseNetworkServer(0)
Else
Debug "Server - Can't create the server (port in use ?)."
EndIf
Client :
Code : Tout sélectionner
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
Debug "Client - Connected To server..."
Debug "Client - A string has been sent To the server ..."
restore start:
For i = 1 To 9
read.s p.s
phrase.s=phrase.s+p.s+";"
nrb_message=nrb_message+1
Next
taille=len( phrase.s)
SendNetworkString(ConnectionID, str(taille)+";"+str(nrb_message+2)+";"+phrase.s, #PB_UTF8)
CloseNetworkConnection(ConnectionID)
Else
Debug "Client - Oops ! Can't find the server (Is it launched ?)."
EndIf
DataSection
start:
data.s "il etait une bergere"
data.s "et ri et ron"
data.s "petit patapon"
data.s "il etait une bergere"
data.s "qui gardait ses moutons"
data.s "ron-ron"
data.s "qui gardait ses moutons"
data.s " rhoooo ! la belle chanson "
data.s "que voila !"
data.s "-1"
fin:
EndDataSection
en clair , limiter le nombre de send-recept String au minimum
et ajouter des indications dans le message (ici taille du message pour le buffer , et nombre de phrases a afficher )
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 8:42
par falsam
Merci Zorro. J'ai testé ton code mais il ne me convient pas car si dans le cadre d'un chat par exemple, un utilisateur utilise le ";" alors ton systeme ne fonctionne pas. Bien sur je pourrais remplacer ce caractère par un autre mais je pense que le risque est le même.
Je pense que je vais passer une chaine JSON entre le client et le serveur.
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 8:48
par Zorro
si dans le cadre d'un chat par exemple, un utilisateur utilise le ";" alors ton systeme ne fonctionne pas. Bien sur je pourrais remplacer ce caractère par un autre mais je pense que le risque est le même.
pas vraiment, n'oublie pas qu'on est en unicode
parmis les nombreux caracteres de l'unicode, il y en a bien un qui peut servir de separateur ...
tu peux aussi mettre un "agent de surveillance" , qui guette , un petit filtre sur les caracteres autorisé , et voila
genre, tu autorises les codes 32 a 127 , et tu prends un caracteres >127 pour faire le separateur
l'imagination au pouvoir

Re: Communication Client Serveur
Publié : lun. 19/sept./2016 9:50
par falsam
Un serveur et un client communiquant avec une structure exporter/importer via JSON
■
Structure commune au serveur et au client-La variable event.s contient un événement.
-La variable message.s contient le message associé.
Exemple :
"
Event_MovetoXY" : Un sprite se déplace - Message contiendra la position x et y du sprite.
"
Event_UserMessage" : Un utilisateur laisse un message - Message contiendra le message utilisateur.
■
Server.pbCode : Tout sélectionner
;Structure Message
Structure NewMessage
event.s
message.s
EndStructure
Global NewList Messages.NewMessage(), Buffer.s, Messages.s
If InitNetwork() = 0
Debug "Server - Can't initialize the network !"
End
EndIf
Port = 6832
*Buffer = AllocateMemory(5120)
If CreateNetworkServer(0, Port)
Debug "Server - Server created (Port "+Str(Port)+")."
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "Server - A new client has connected !"
Case #PB_NetworkEvent_Data
Debug "Server - Client "+Str(ClientID)+" has send a packet !"
FreeMemory(*Buffer)
*Buffer = AllocateMemory(5120)
;Receiving the message
ReceiveNetworkData(ClientID, *Buffer, 5120)
Buffer = PeekS(*Buffer, -1, #PB_UTF8)
;JSON formatting
Messages = "[" + LSet(Buffer, Len(Buffer)-1) + "]"
;Send the JSON string to the linked list messages()
If ParseJSON(0, Messages)
ExtractJSONList(JSONValue(0), Messages())
ForEach Messages()
Debug Messages()\event + " " + Messages()\message
Next
Else
Debug "Serveur - Error JSON " + JSONErrorMessage() + " " + JSONErrorPosition()
EndIf
Case #PB_NetworkEvent_Disconnect
Debug "Server - Client " + Str(ClientID)+" has closed the connection..."
EndSelect
EndIf
ForEver
CloseNetworkServer(0)
Else
Debug "Server - Can't create the server (port in use ?)."
EndIf
■
Client.pbCode : Tout sélectionner
Structure NewMessage
event.s
message.s
EndStructure
Global Message.NewMessage
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
Debug "Client - Connected To server..."
;Send 100 messages
Debug "Client - A string has been sent To the server ..."
For i = 0 To 99
With Message
\event = "Event" + i
\message = "Message" + i
;JSON formatting
If CreateJSON(0)
InsertJSONStructure(JSONValue(0), @Message, NewMessage)
SendNetworkString(ConnectionID, ComposeJSON(0) + ",")
EndIf
EndWith
Next
CloseNetworkConnection(ConnectionID)
Else
Debug "Client - Oops ! Can't find the server (Is it launched ?)."
EndIf
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 10:48
par falsam
Jusqu'à présent la communication fonctionnait que dans le sens Client -> Serveur.
Avec les codes qui suivent, le client va emettre 100 messages vers le serveur comme dans le code précédent mais aussi recevoir le message de bienvenu du serveur.
■
Client.pbCode : Tout sélectionner
Structure NewMessage
event.s
message.s
EndStructure
;Send message
Global Message.NewMessage
;Receive message(s)
Global NewList Messages.NewMessage(), Buffer.s, Messages.s
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
*Buffer = AllocateMemory(5120)
Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
Debug "Client - Connected To server..."
;Send 100 messages
Debug "Client - A string has been sent To the server ..."
For i = 0 To 99
With Message
\event = "Event" + i
\message = "Message" + i
;JSON formatting
If CreateJSON(0)
InsertJSONStructure(JSONValue(0), @Message, NewMessage)
SendNetworkString(ConnectionID, ComposeJSON(0) + ",")
EndIf
EndWith
Next
Repeat
Connection = NetworkClientEvent(ConnectionID)
If Connection
Select Connection
Case #PB_NetworkEvent_Data
Debug "Client - Server has send a packet !"
FreeMemory(*Buffer)
*Buffer = AllocateMemory(5120)
;Receiving the message
ReceiveNetworkData(ConnectionID, *Buffer, 5120)
Buffer = PeekS(*Buffer, -1, #PB_UTF8)
;JSON formatting
Messages = "[" + LSet(Buffer, Len(Buffer)-1) + "]"
;Send the JSON string to the linked list messages()
If ParseJSON(0, Messages)
ExtractJSONList(JSONValue(0), Messages())
ForEach Messages()
Debug Messages()\event + " " + Messages()\message
Next
Else
Debug "Serveur - Error JSON " + JSONErrorMessage() + " " + JSONErrorPosition()
EndIf
EndSelect
EndIf
ForEver
CloseNetworkConnection(ConnectionID)
Else
Debug "Client - Oops ! Can't find the server (Is it launched ?)."
EndIf
■
Server.pbCode : Tout sélectionner
;Structure Message
Structure NewMessage
event.s
message.s
EndStructure
;Send message
Global Message.NewMessage
;Receive message(s)
Global NewList Messages.NewMessage(), Buffer.s, Messages.s
If InitNetwork() = 0
Debug "Server - Can't initialize the network !"
End
EndIf
Port = 6832
*Buffer = AllocateMemory(5120)
If CreateNetworkServer(0, Port)
Debug "Server - Server created (Port "+Str(Port)+")."
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
Select SEvent
Case #PB_NetworkEvent_Connect
Debug "Server - A new client has connected !"
;Send welcome message
With Message
\event = "Event_ServerMessage"
\message = "Hello"
;JSON formatting
If CreateJSON(0)
InsertJSONStructure(JSONValue(0), @Message, NewMessage)
SendNetworkString(ClientID, ComposeJSON(0) + ",")
EndIf
EndWith
Case #PB_NetworkEvent_Data
Debug "Server - Client "+Str(ClientID)+" has send a packet !"
FreeMemory(*Buffer)
*Buffer = AllocateMemory(5120)
;Receiving the message
ReceiveNetworkData(ClientID, *Buffer, 5120)
Buffer = PeekS(*Buffer, -1, #PB_UTF8)
;JSON formatting
Messages = "[" + LSet(Buffer, Len(Buffer)-1) + "]"
;Send the JSON string to the linked list messages()
If ParseJSON(0, Messages)
ExtractJSONList(JSONValue(0), Messages())
ForEach Messages()
Debug Messages()\event + " " + Messages()\message
Next
Else
Debug "Serveur - Error JSON " + JSONErrorMessage() + " " + JSONErrorPosition()
EndIf
Case #PB_NetworkEvent_Disconnect
Debug "Server - Client " + Str(ClientID)+" has closed the connection..."
EndSelect
EndIf
ForEver
CloseNetworkServer(0)
Else
Debug "Server - Can't create the server (port in use ?)."
EndIf
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 10:57
par djes
Pour info, j'avais fait un code client/serveur il y a longtemps. J'avais fait un truc de ce genre :
Code : Tout sélectionner
SEvent = NetworkServerEvent()
If SEvent
ClientID.l = NetworkClientID()
Select SEvent
;New client
Case 1
;A client is leaving
Case 4
CloseNetworkConnection(ClientID)
;Raw data has been received
Case 2
done.l = #False ;if done then close socket, either gracefull or due to an error
Repeat
ClearBuffer()
RequestLength = ReceiveNetworkData(ClientID, *buffer, 4096)
If RequestLength > 0
TraiteRequete()
ElseIf RequestLength = 0
Done = #True
Else
Error = WSAGetLastError_()
If Error = #WSAEWOULDBLOCK ;we are non-blocking so: no more data to read
Delay(100)
Done = #True ;so close the socket
ElseIf Error <> 0
Done = #True
EndIf
EndIf
Until Done = #True
EndSelect
EndIf
Edit : Ah, oui, mais j'utilisais le mode asynchrone, avec
Code : Tout sélectionner
#FD_ALL = #FD_OOB|#FD_ACCEPT|#FD_CONNECT|#FD_CLOSE
WSAAsyncSelect_(socket, WindowID(0), #WM_NULL, #FD_ALL)
Je ne sais pas si c'est encore utile...
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 11:22
par falsam
Merci djes de te pencher sur ce sujet.
djes a écrit :Je ne sais pas si c'est encore utile...
Hum hum je ne sais pas si ça répond à la question relative à la concaténation des messages qui me préoccupe actuellement ^^
La solution JSON me plait bien. Je vais tacher de mettre en place une toute petite démo Tchat + 2D moins barbante que cette étalages de codes que j'ai pu produire.
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 12:12
par djes
falsam a écrit :Merci djes de te pencher sur ce sujet.
djes a écrit :Je ne sais pas si c'est encore utile...
Hum hum je ne sais pas si ça répond à la question relative à la concaténation des messages qui me préoccupe actuellement ^^
La solution JSON me plait bien. Je vais tacher de mettre en place une toute petite démo Tchat + 2D moins barbante que cette étalages de codes que j'ai pu produire.
Oui, pour la concaténation, tu as raison, mais je pense que tu as vu pourquoi j'ai posté ça

Pour JSON pourquoi pas ; en tous cas, je ne trouve pas que tes démos soient barbantes.
Re: Communication Client Serveur
Publié : lun. 19/sept./2016 13:03
par Zorro
djes a écrit :Pour JSON pourquoi pas ; en tous cas, je ne trouve pas que tes démos soient barbantes.
tain..... laisse le, pour une fois qu'il a un éclair de lucidité
Arf ... Sorry c'etait vraiment trop tentant

Re: Communication Client Serveur
Publié : lun. 19/sept./2016 14:40
par Kwai chang caine
J'ai une question qui me taraude depuis un bon moment, et puisque vous parlez de client/serveur
Mon geek m'avait parlé d'un truc que je croyais pas possible, mais je me rappelle plus le nom
Une histoire de client/serveur qui se connectaient en "dual je sais pas quoi" ou "half" ou un truc comme ça, qui permettait de se connecter entre eux bien plus facilement que comme on fait nous avec client/serveur, sans rentrer d'IP....
J'ai rêvé ???

Re: Communication Client Serveur
Publié : lun. 19/sept./2016 22:13
par falsam
falsam a écrit :je pense que tu as vu pourquoi j'ai posté ça
Rhaaa je déteste. Ca doit être tellement évident que je ne vois pas.
Re: Communication Client Serveur
Publié : mar. 20/sept./2016 7:17
par djes
falsam a écrit :falsam a écrit :je pense que tu as vu pourquoi j'ai posté ça
Rhaaa je déteste. Ca doit être tellement évident que je ne vois pas.
Sans aucun doute ! En plus il y a deux trucs au moins !