Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

questions sur un client/serveur utilisant un tube nomm

13 réponses
Avatar
torri
j'ai écrit un client/serveur utilisant les tubes nommés. Le serveur
utilise l'overlapped I/O (je ne sais pas comment trraduire ceci). Je me
suis inspiré beaucoup de [1] et [2] car je ne connais pas énormément de
choses à propos des tubes nommés et des clients/serveurs. Voici mes codes:

Le serveur: http://www.maths.univ-evry.fr/pages_perso/vtorri/files/
server2.c

Le client: http://www.maths.univ-evry.fr/pages_perso/vtorri/files/
client2.c

Donc, dans le code du serveur (uniquement pour l'instant), quand je veux
lire des données, je lance un thread avec une boucle sur PeekNamedPipe(),
et dès qu'il y a des données, je quitte le thread. Puis quand
WaitForMultipleObjects() me rend la main lorque que le thread se termine,
je fais une boucle sur ReadFile() et je récupère les données.

Je voudrais savoir s'il existe un moyen de savoir si des données sont
disponibles avec WaitForMultipleObjects(), celle-ci retournant quand une
donnée doit être lue, plutôt que créer un thread avec PeekNamedPipe()
(j'aimerais éviter les threads le plus possible. En plus il me prend 100%
du CPU).

L'autre question : pour quitter le client, je fais juste un CloseHandle
sur l'handle renvoyé par CreateFile(). Mais je n'arrive pas, côté
serveur, à savoir si le client s'est déconnecté. Comment dois-je faire
pour que le serveur soit notifié de la déconnection du client ? (pareil
dans l'auter sens : si le serveur se déconnecte, comment le client peut
le savoir)

Merci

10 réponses

1 2
Avatar
Steph
"torri" a écrit dans le message de news:
imivr2$uld$
Je voudrais savoir s'il existe un moyen de savoir si des données sont
disponibles avec WaitForMultipleObjects(), celle-ci retournant quand une
donnée doit être lue, plutôt que créer un thread avec PeekNamedPipe()
(j'aimerais éviter les threads le plus possible. En plus il me prend 100%
du CPU).

L'autre question : pour quitter le client, je fais juste un CloseHandle
sur l'handle renvoyé par CreateFile(). Mais je n'arrive pas, côté
serveur, à savoir si le client s'est déconnecté. Comment dois-je faire
pour que le serveur soit notifié de la déconnection du client ? (pareil
dans l'auter sens : si le serveur se déconnecte, comment le client peut
le savoir)



Regarde les exemples c/s du Sdk Microsoft sur les pipes (Winbase ou
Security)
Déjà tu devrais utiliser ConnectNamedPipe()..
Avatar
torri
On Sat, 26 Mar 2011 11:33:35 +0100, Steph wrote:

"torri" a écrit dans le message de news:

L'autre question : pour quitter le client, je fais juste un CloseHandle
sur l'handle renvoyé par CreateFile(). Mais je n'arrive pas, côté
serveur, à savoir si le client s'est déconnecté. Comment dois-je faire
pour que le serveur soit notifié de la déconnection du client ? (pareil
dans l'auter sens : si le serveur se déconnecte, comment le client peut
le savoir)



Regarde les exemples c/s du Sdk Microsoft sur les pipes (Winbase ou
Security)
Déjà tu devrais utiliser ConnectNamedPipe()..



j'utilise ConnectNamedPipe() (regarde dans server2.c)

Je n'ai pas le SDK. Ces sources sont dispo sur le web ?

merci
Avatar
torri
On Sat, 26 Mar 2011 11:33:35 +0100, Steph wrote:

"torri" a écrit dans le message de news:

L'autre question : pour quitter le client, je fais juste un CloseHandle
sur l'handle renvoyé par CreateFile(). Mais je n'arrive pas, côté
serveur, à savoir si le client s'est déconnecté. Comment dois-je faire
pour que le serveur soit notifié de la déconnection du client ? (pareil
dans l'auter sens : si le serveur se déconnecte, comment le client peut
le savoir)



Regarde les exemples c/s du Sdk Microsoft sur les pipes (Winbase ou
Security)
Déjà tu devrais utiliser ConnectNamedPipe()..



j'utilise ConnectNamedPipe() (regarde dans server2.c)

Je n'ai pas le SDK. Ces sources sont dispo sur le web ?

merci
Avatar
torri
On Sat, 26 Mar 2011 11:33:35 +0100, Steph wrote:

"torri" a écrit dans le message de news:

L'autre question : pour quitter le client, je fais juste un CloseHandle
sur l'handle renvoyé par CreateFile(). Mais je n'arrive pas, côté
serveur, à savoir si le client s'est déconnecté. Comment dois-je faire
pour que le serveur soit notifié de la déconnection du client ? (pareil
dans l'auter sens : si le serveur se déconnecte, comment le client peut
le savoir)



Regarde les exemples c/s du Sdk Microsoft sur les pipes (Winbase ou
Security)
Déjà tu devrais utiliser ConnectNamedPipe()..



j'utilise ConnectNamedPipe() (regarde dans server2.c)

Je n'ai pas le SDK. Ces sources sont dispo sur le web ?

merci
Avatar
Steph
"torri" a écrit dans le message de news:
imkifq$8o7$
On Sat, 26 Mar 2011 11:33:35 +0100, Steph wrote:

"torri" a écrit dans le message de news:


j'utilise ConnectNamedPipe() (regarde dans server2.c)



Ah oui, désolé, je regardais un autre source ..

Je n'ai pas le SDK. Ces sources sont dispo sur le web ?



Téléchargeable chez Microsoft ("Windows SDK")
C'est indispensable pour partir sur de bons exemples
Avatar
torri
On Sat, 26 Mar 2011 13:16:48 +0100, Steph wrote:


Je n'ai pas le SDK. Ces sources sont dispo sur le web ?



Téléchargeable chez Microsoft ("Windows SDK") C'est indispensable pour
partir sur de bons exemples



Je l'ai téléchargé, regardé la partie serveur et j'ai compris. J'ai fait
un peu différemment du SDK. Je garde mon thread et mon PeekNamedPipe().
Et quand le client se déconnecte, PeekNamedPipe() foire et GetLastError()
vaut ERROR_BROKEN_PIPE (comme ReadFile(), d'ailleurs. Ce n'est pas
étonnant car MSDN dit que PeekNamedPipe() est presque un ReadFile())

Donc je rajoute un event de sortie, je le signale quand il y a cette
erreur et je gère ça avec WaitForMultipleObjects()

C'est une affaire qui roule bien :-)

Je vais néanmoins lire la partie client du SDK, on ne sait jamais s'il y
a de bonnes choses à prendre pour ce que je veux faire

Merci
Avatar
torri
On Fri, 25 Mar 2011 21:01:22 +0000, torri wrote:

j'ai écrit un client/serveur utilisant les tubes nommés. Le serveur
utilise l'overlapped I/O (je ne sais pas comment trraduire ceci). Je me
suis inspiré beaucoup de [1] et [2] car je ne connais pas énormément de
choses à propos des tubes nommés et des clients/serveurs. Voici mes
codes:

Le serveur: http://www.maths.univ-evry.fr/pages_perso/vtorri/files/" target="_blank" class="text-blue hover:opacity-90 " style="word-break: break-all;" rel="noopener nofollow">http://www.maths.univ-evry.fr/pages_perso/vtorri/files/
server2.c

Le client: http://www.maths.univ-evry.fr/pages_perso/vtorri/files/" target="_blank" class="text-blue hover:opacity-90 " style="word-break: break-all;" rel="noopener nofollow">http://www.maths.univ-evry.fr/pages_perso/vtorri/files/
client2.c



j'ai encore une question existencielle concernant la lecture des données
(côté client ou serveur). Je ne vais parler que de la partie serveur,
dont le tube a été ouvert en overlapped.

Pour l'instant, je lance un thread qui va continuellement essayer de lire
le tube avec une boucle infinie. Dedans, je fais un

PeekNamedPipe(svr->pipe, NULL, 0, NULL, &nbr_bytes, NULL)

* si PeekNamedPipe() réussi et nbr_bytes > 0 je crée un buffer de taille
nbr_bytes et je le passe à ReadFile()
* si PeekNamedPipe() échoue et l'erreur GetLastError() retourne
ERROR_BROKEN_PIPE, ça veut dire que le client s'est déconnecté et je sort
correctement (j'ai un event global que je signale dans ce cas précis).

J'aime bien cette version car je passe à ReadFile un buffer de la bonne
taille et toutes les données sont lues.

Voici le code du thread : http://dpaste.org/rpVY/ Je peux l'améliorer car
pour linstant, quand PeekNamedPipe() réussi, je sors, j'appelle ReadFile
et je relance le thread. autant faire le ReadFile() après svr->read_count
= nbr_bytes; et remplacer break par continue.

Maintenant, j'ai regardé le SDK (Server32.c) et il font différemment. Il
y a toujours une boucle infinie. ReadFile est appelé avec la structure
OVERLAPPED.

Si ReadFile() échoue, on regarde la valeur de GetLastError():
* ERROR_IO_PENDING : WaitForSingleObject() est appelé avec l'event de
l'overlapped.
* ERROR_BROKEN_PIPE : le client s'est déconnecté, on sort
* autre erreur : ça ne devrait pas arriver mais on sort quand même

Après GetOverlappedResult() est appelé (que ReadFile() ait échoué avec
ERROR_IO_PENDING ou bien qu'il ait réussi).

Voici la partie intéressante du code de Server32.c :

http://dpaste.org/z2Or/

Ce qui me gêne ici est que on doit passer un buffer de taille fixe et les
données envoyées par le client peuvent avoir une taille plus importante
que la taille du buffer que l'on passe à ReadFile().

Donc, supposons que je m'inspire du code de Server32.c, avec un buffer de
taille 2 octets que je passe à ReadFile() et que le client envoie les 5
octets "rampe" (je donne ces valeurs pour fixer les idées c'est la même
chose si on multiplie tout par 1000). Que dois-je faire pour avoir, du
côté serveur, un buffer de 5 octets rempli avec les 5 octets envoyes par
le client ?

merci
Avatar
patrick
On 27 mar, 09:26, torri wrote:
Donc, supposons que je m'inspire du code de Server32.c, avec un buffer de
taille 2 octets  que je passe à ReadFile() et que le client envoie le s 5
octets "rampe" (je donne ces valeurs pour fixer les idées c'est la mê me
chose si on multiplie tout par 1000). Que dois-je faire pour avoir, du
côté serveur, un buffer de 5 octets rempli avec les 5 octets envoyes par
le client ?
merci



Dans ce cas, la boucle devrait en principe s'exécuter 3 fois : 2 + 2 +
1
Avatar
torri
On Sun, 27 Mar 2011 10:01:11 -0700, patrick wrote:

Dans ce cas, la boucle devrait en principe s'exécuter 3 fois : 2 + 2 + 1



Hmm, je remets la question car je pense que tu l'as loupée :

Que dois-je faire pour avoir, du côté serveur, un buffer de 5 octets
rempli avec les 5 octets envoyes par le client ?

Donc, ce que je veux n'est pas le nombre de fois que la boucle est
exécutée (en étant prof de math dans la vraie vie, j'avais subtilement
déjà calculé ce nombre), mais un code faisant ce que j'ai décrit

merci
Avatar
torri
On Mon, 28 Mar 2011 11:54:08 +0200, Antoine wrote:

Oui, c'est le meme principe dans tous les exemples de MS On choisit un
buffer de taille fixe ou dynamique (malloc-realloc), qui se remplit en
bouclant sur une api de lecture (ReadFile, InternetReadFile, ..)



dans ce cas, j'ai un problème. J'ai ouvert le pipe en overlapped, donc
ReadFile() et WriteFile() peuvent retourner tout de suite si l'opération
prend trop de temps (le code d'erreur retourné par ces 2 fonctions est
ERROR_IO_PENDING dans ce cas). ReadFile() renvoie cette erreur, mais je
n'arrive pas à m'en sortir avec les events

Voici le code du serveur avec la méthode du SDK (le client est dans le
1er post, son code n'a pas changé):

http://dpaste.org/crQq/

En gros:

dans mon thread principal, je fais une boucle infinie qui appelle
WaitForMultipleobjects(). Il y a 2 ou 3 objects qui sont gérés : l'event
du pipe, un event général pour quitter la boucle et en 3ème un event pour
ReadFile().

une fois que le client se connecte, je lance un thread qui fait une
boucle infinie pour lire les données arrivant du client. ReadFile() est
appelé et je gère l'erreur.

Dès qu'une donnée arrive du client, ERROR_IO_PENDING est retourné et je
n'arrive pas à faire en sorte que WaitForMultipleObjects() retourne quand
j'appelle SetEvent().

J'ai essayé beaucoup de choses (avoir l'event dès le début, le rajouter
en cours de route, etc...). Rien à faire, je n'arrive pas à faire
fonctionner correctement ReadFile().

Donc si quelqu'un a une idée...

merci
1 2