Re: Socket IP

Page principale

Répondre à ce message
Auteur: Frederic Mantegazza
Date:  
À: guilde
Sujet: Re: Socket IP
Cazenave Frederic wrote:
>
> Si je casse un serveur alors que des donnees sont
> encore en attente de lecture, il semble que je ne
> puisse pas relancer le serveur tous de suite !!!
>


Etrange, ca. Je n'ai pas remarque. Je vais faire des tests.

> Je cherche donc a purger mon port afin de relancer
> mon serveur (mon serveur est toujours sur un port
> fixe)
>
> Dans mon premier mail je parle de client car en fait
> des info sont echangees dans les deus sens. Tantot le
> prg est client tantot serveur.


Attention, ce n'est pas parce que des donnees vont dans les deux sens
que le client se transforme en serveur et vice-versa. Celui qui est a
l'ecoute d'une connexion est le serveur (celui qui se bind()).
Maintenant, si alternativement tes deux applis font ca, alors ok. Suffit
de bien se comprendre.

>
> Une aute question est venue depuis :
>
> Comment peut on passer une connexion sous tcp/ip
> a un autre processus :
>
> J ai un procesus serveur qui attent des requetes. Des
> qu'une requete se presente, il la traduit puis passe
> les infos a un autre processus Reponse(on utilise pas
> de fork le processus existe deja) et lui demande de
> retourner les resultats par la meme connexion que celle
> etablit avec le client.
>
> Je ne sais pas transferer la connexion .
>


Je ne suis pas sur que cela soit possible. Meme si tu arrives a donner
le no de descripteur (celui retourne par accept()) a Reponse, il n'aura
pas le droit de lire et ecrire dessus. Il faut que Reponse soit forke
par Serveur pour heriter des chemins ouverts.

Je pense qu'il faut que tu revois la facon de dialoguer.

A titre d'infos, voici la facon dont j'ai gere les echanges entre deux
machines :

Calculateur = machine de pilotage (Alpha)
Baie        = baie electronique (tourne sous OS9)
Main        = process tournant dur Calculateur
Client      = process forke par Main pour dialoguer avec Bai
Serveur     = process tournant sur Baie.
Exec        = process forke par Serveur


Lorsque Main veut envoyer un ordre a Baie, il place les donnees dans un
pipe, puis il forke le process Client, en lui passant comme arguments
les descripteurs de lecture et d'ecriture du pipe ouvert. Puis il entre
dans une boucle d'attente du style :

    while (!reponse) {
        sleep(0);
    }


Client recupere les donnees sur le pipe, etablit la connexion avec
Serveur (socket(), puis connect()), envoie les donnees sur le socket,
puis se met a l'ecoute de ce socket (un read(), qui est bloquant).

Pendant ce temps, Serveur a detecte une demande de connexion (accept()).
Il place les donnees dans un pipe, puis forke Exec en lui passant comme
arguments les decripteurs de lecture et d'ecriture de ce pipe, ainsi que
le no du socket. Ensuite il ferme le socket (celui retourne par accept,
pas le 'maitre' retourne par socket, qui doit lui rester ouvert pour les
futures connexions), et se remet en attente d'une connexion (avec
accept()).

Exec recupere les donnees sur le pipe, les traite, et lorsqu'il a fini,
c'est lui qui envoie la reponse a Client par le socket passe en
argument. Il n'a plus qu'a tout refermer et a se terminer.

Client lit donc cette reponse. Pour prevenir Main qu'il a fini, il place
cette reponse dans le pipe (le tout premier dont j'ai parle), puis se
termine. Il faut bien sur placer dans Main une routine d'interception du
signal SIGCHILD, qui est envoye a la mort d'un fils. Dans cette routine,
tu met le flag reponse a 1, tout simplement. Main va donc sortir de sa
boucle et n'a plus qu'a lire les donnees dans le pipe (sans oublier de
faire un petit wait() pour eviter les zombies).

Ce wait te permet meme de recuperer le status du fils (Client) qui peux
retourner des erreurs (s'il a perdu la connexion, par exemple).

Si tu veux quelques precisions sur les valeurs retournees par read
lorsqu'il y a perte de liaison, dis-le moi.

En fait, mon process Main ne tourne pas tout a fait comme ca. C'est dans
la routine d'interception de SIGCHILD que je relis le pipe. Main, lui,
peut faire autre chose, par exemple envoyer un nouvel ordre avant que
l'autre ne soit revenu. Par contre, cela implique de garder trace des
numeros de pipes, en fonction du pid du fils auquel il est ratache (le
wait() permet de recuperer le pid du fils, donc de retrouver ce numero
de pipe).

Voila. Si tu veux plus d'infos, n'hesite pas a me recontacter.


Frederic