On Jul 30, 3:49 pm, Olivier Miakinen :Pourtant, en regardant ton code il me semble bien que l'intuition
du Forgeron était bonne, et que tu ouvres et fermes la connexion
à chaque fois.
Tu parles de l'appel a fSetTxSock(), comment
puis-je proceder sans l'etablir a chaque fois ?
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qui
plus est, tu commences par fermer la précédente : t'es-tu assuré que
tout avait été envoyé ?
Non, car je suppose que l'emission precedente est forcement
partie puisque je ne la termine que lorsque send() retourne zero.
La fermeture de socket ne se realise qu'en quittant fSendBuffer();
(doute : est-ce que ca se tient ?)
Non, cette socket est bloquante, et je suppose que la fonction
send() ne rend la main qu'apres avoir envoye les donnees.
C'est pour cela que je boucle dessus pour envoyer
tous les blocs de donnees les uns apres les autres.
D'apres toi il semble que le probleme se situe a l'emission ?
Et non a la reception : est-ce que fListen() te semble correct ?
Comment m'y prendre pour envoyer sans ouvrir une sock via fSetTxSock
() ?
On Jul 30, 3:49 pm, Olivier Miakinen :
Pourtant, en regardant ton code il me semble bien que l'intuition
du Forgeron était bonne, et que tu ouvres et fermes la connexion
à chaque fois.
Tu parles de l'appel a fSetTxSock(), comment
puis-je proceder sans l'etablir a chaque fois ?
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qui
plus est, tu commences par fermer la précédente : t'es-tu assuré que
tout avait été envoyé ?
Non, car je suppose que l'emission precedente est forcement
partie puisque je ne la termine que lorsque send() retourne zero.
La fermeture de socket ne se realise qu'en quittant fSendBuffer();
(doute : est-ce que ca se tient ?)
Non, cette socket est bloquante, et je suppose que la fonction
send() ne rend la main qu'apres avoir envoye les donnees.
C'est pour cela que je boucle dessus pour envoyer
tous les blocs de donnees les uns apres les autres.
D'apres toi il semble que le probleme se situe a l'emission ?
Et non a la reception : est-ce que fListen() te semble correct ?
Comment m'y prendre pour envoyer sans ouvrir une sock via fSetTxSock
() ?
On Jul 30, 3:49 pm, Olivier Miakinen :Pourtant, en regardant ton code il me semble bien que l'intuition
du Forgeron était bonne, et que tu ouvres et fermes la connexion
à chaque fois.
Tu parles de l'appel a fSetTxSock(), comment
puis-je proceder sans l'etablir a chaque fois ?
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qui
plus est, tu commences par fermer la précédente : t'es-tu assuré que
tout avait été envoyé ?
Non, car je suppose que l'emission precedente est forcement
partie puisque je ne la termine que lorsque send() retourne zero.
La fermeture de socket ne se realise qu'en quittant fSendBuffer();
(doute : est-ce que ca se tient ?)
Non, cette socket est bloquante, et je suppose que la fonction
send() ne rend la main qu'apres avoir envoye les donnees.
C'est pour cela que je boucle dessus pour envoyer
tous les blocs de donnees les uns apres les autres.
D'apres toi il semble que le probleme se situe a l'emission ?
Et non a la reception : est-ce que fListen() te semble correct ?
Comment m'y prendre pour envoyer sans ouvrir une sock via fSetTxSock
() ?
> comment puis-je proceder sans l'etablir a chaque fois ?
En mettant l'ouverture de la socket à l'exterieur de ta boucle d'emissi on, en
préliminaire, et en réservant la fermeture à la fin de ta transmiss ion globale, lorsque le
dernier acquittement a été reçu. (et normalement, tu n'aurais pas à faire tes
ack/time-out/retry)!
En outre, tu sembles utilisé deux connexions, via 2 sockets: une pour c haque sens.
C'est inutile, une même socket peut servir à recevoir et a émettre.
Même dans des threads différents, l'un peut écrire dedans pendant q u'un autre lit.
(Ou alors l'implémentation de MS est nulle, et ça m'étonnerait quan d même beaucoup.)
Problème: send() rend la main lorsqu'il a accepté les données pour son buffer, pas
lorsqu'elles sont arrivés en face.
Ton code indique le contraire de ton indication: il ferme lorsque send() a accepté le
dernier octet. Pas retourné 0.
L'utilisation de Sleep me laisse sans voix.
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais v a falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Analogie: tu fais des frites chez McDo.
Ton code actuel remplit la friteuse d'huile, la chauffe, fait une portion de frites,
vidange la friteuse et la passe au lave-vaisselle... pour CHAQUE portion de frites!
Dans la limite de la législation alimentaire, ne te semblerait-il pas p lus économique de:
Remplir la friteuse d'huile et la chauffer,
puis faire des portions de frites les unes après les autres selon la de mande,
et seulement en fin de service, vidanger la friteuse et la laver.
Et je manque d'analogie pour expliquer que les codes d'erreurs, tes acks, doivent aussi
remonter dans la même socket, et non dans une socket séparée (mêm e avec un thread séparé
de traitement).
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
tant que la communication TCP est debout, la socket est contente et tu n' as pas
d'erreur. Par contre, si tu dois avoir un traitement des cas d'erreurs av ec diagnostique
et tout, recevoir des messages de celui à l'autre bout peut être util e, parce que la
socket seule va être un peu trop "simple")
D'après moi, mais je ne sais pas comment le dire gentiment, le problè me est dans la
conception de la solution utilisée... faudrait revoir l'architecture en posant le problème
simplement (problématique dont on ne nous a rien dit, alors pour aider, je vais être un
peu sec sur le sujet).
Voilà, rien de personnel, mais rester détaché n'est pas forcément facile.
> comment puis-je proceder sans l'etablir a chaque fois ?
En mettant l'ouverture de la socket à l'exterieur de ta boucle d'emissi on, en
préliminaire, et en réservant la fermeture à la fin de ta transmiss ion globale, lorsque le
dernier acquittement a été reçu. (et normalement, tu n'aurais pas à faire tes
ack/time-out/retry)!
En outre, tu sembles utilisé deux connexions, via 2 sockets: une pour c haque sens.
C'est inutile, une même socket peut servir à recevoir et a émettre.
Même dans des threads différents, l'un peut écrire dedans pendant q u'un autre lit.
(Ou alors l'implémentation de MS est nulle, et ça m'étonnerait quan d même beaucoup.)
Problème: send() rend la main lorsqu'il a accepté les données pour son buffer, pas
lorsqu'elles sont arrivés en face.
Ton code indique le contraire de ton indication: il ferme lorsque send() a accepté le
dernier octet. Pas retourné 0.
L'utilisation de Sleep me laisse sans voix.
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais v a falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Analogie: tu fais des frites chez McDo.
Ton code actuel remplit la friteuse d'huile, la chauffe, fait une portion de frites,
vidange la friteuse et la passe au lave-vaisselle... pour CHAQUE portion de frites!
Dans la limite de la législation alimentaire, ne te semblerait-il pas p lus économique de:
Remplir la friteuse d'huile et la chauffer,
puis faire des portions de frites les unes après les autres selon la de mande,
et seulement en fin de service, vidanger la friteuse et la laver.
Et je manque d'analogie pour expliquer que les codes d'erreurs, tes acks, doivent aussi
remonter dans la même socket, et non dans une socket séparée (mêm e avec un thread séparé
de traitement).
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
tant que la communication TCP est debout, la socket est contente et tu n' as pas
d'erreur. Par contre, si tu dois avoir un traitement des cas d'erreurs av ec diagnostique
et tout, recevoir des messages de celui à l'autre bout peut être util e, parce que la
socket seule va être un peu trop "simple")
D'après moi, mais je ne sais pas comment le dire gentiment, le problè me est dans la
conception de la solution utilisée... faudrait revoir l'architecture en posant le problème
simplement (problématique dont on ne nous a rien dit, alors pour aider, je vais être un
peu sec sur le sujet).
Voilà, rien de personnel, mais rester détaché n'est pas forcément facile.
> comment puis-je proceder sans l'etablir a chaque fois ?
En mettant l'ouverture de la socket à l'exterieur de ta boucle d'emissi on, en
préliminaire, et en réservant la fermeture à la fin de ta transmiss ion globale, lorsque le
dernier acquittement a été reçu. (et normalement, tu n'aurais pas à faire tes
ack/time-out/retry)!
En outre, tu sembles utilisé deux connexions, via 2 sockets: une pour c haque sens.
C'est inutile, une même socket peut servir à recevoir et a émettre.
Même dans des threads différents, l'un peut écrire dedans pendant q u'un autre lit.
(Ou alors l'implémentation de MS est nulle, et ça m'étonnerait quan d même beaucoup.)
Problème: send() rend la main lorsqu'il a accepté les données pour son buffer, pas
lorsqu'elles sont arrivés en face.
Ton code indique le contraire de ton indication: il ferme lorsque send() a accepté le
dernier octet. Pas retourné 0.
L'utilisation de Sleep me laisse sans voix.
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais v a falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Analogie: tu fais des frites chez McDo.
Ton code actuel remplit la friteuse d'huile, la chauffe, fait une portion de frites,
vidange la friteuse et la passe au lave-vaisselle... pour CHAQUE portion de frites!
Dans la limite de la législation alimentaire, ne te semblerait-il pas p lus économique de:
Remplir la friteuse d'huile et la chauffer,
puis faire des portions de frites les unes après les autres selon la de mande,
et seulement en fin de service, vidanger la friteuse et la laver.
Et je manque d'analogie pour expliquer que les codes d'erreurs, tes acks, doivent aussi
remonter dans la même socket, et non dans une socket séparée (mêm e avec un thread séparé
de traitement).
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
tant que la communication TCP est debout, la socket est contente et tu n' as pas
d'erreur. Par contre, si tu dois avoir un traitement des cas d'erreurs av ec diagnostique
et tout, recevoir des messages de celui à l'autre bout peut être util e, parce que la
socket seule va être un peu trop "simple")
D'après moi, mais je ne sais pas comment le dire gentiment, le problè me est dans la
conception de la solution utilisée... faudrait revoir l'architecture en posant le problème
simplement (problématique dont on ne nous a rien dit, alors pour aider, je vais être un
peu sec sur le sujet).
Voilà, rien de personnel, mais rester détaché n'est pas forcément facile.
En outre, tu sembles utilisé deux connexions, via 2 sockets: [...]
Je croyais qu'il fallait une socket pour [IP:PORT] du PC local
et une autre pour [IP:PORT] du PC distant ?
L'utilisation de Sleep me laisse sans voix.
Dommage, mais je crois que tu veux dire qu'il ne sert a rien ?
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais va falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Ok je vais eplucher la doc de select();
Analogie: tu fais des frites chez McDo.
[...]
Bon, pas ma peine de me parler d'une facon aussi stupide, ce n'est
pas
parce-que je n'ecris pas tous les jours des softs de com que je suis
debile.
Je prefere largement que tu me parles avec des termes techniques,
meme
si apres je dois plonger dans la doc pour comprendre les informations.
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
Non, la com entre les deux PC se fait bien dans les deux sens.
Le meme programme tourne sur les deux PC et chacun
peut prendre l'initiative d'envoyer des donees,
c'est pourquoi je pensais qu'il fallait deux sockets.
En outre, tu sembles utilisé deux connexions, via 2 sockets: [...]
Je croyais qu'il fallait une socket pour [IP:PORT] du PC local
et une autre pour [IP:PORT] du PC distant ?
L'utilisation de Sleep me laisse sans voix.
Dommage, mais je crois que tu veux dire qu'il ne sert a rien ?
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais va falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Ok je vais eplucher la doc de select();
Analogie: tu fais des frites chez McDo.
[...]
Bon, pas ma peine de me parler d'une facon aussi stupide, ce n'est
pas
parce-que je n'ecris pas tous les jours des softs de com que je suis
debile.
Je prefere largement que tu me parles avec des termes techniques,
meme
si apres je dois plonger dans la doc pour comprendre les informations.
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
Non, la com entre les deux PC se fait bien dans les deux sens.
Le meme programme tourne sur les deux PC et chacun
peut prendre l'initiative d'envoyer des donees,
c'est pourquoi je pensais qu'il fallait deux sockets.
En outre, tu sembles utilisé deux connexions, via 2 sockets: [...]
Je croyais qu'il fallait une socket pour [IP:PORT] du PC local
et une autre pour [IP:PORT] du PC distant ?
L'utilisation de Sleep me laisse sans voix.
Dommage, mais je crois que tu veux dire qu'il ne sert a rien ?
(là, un petit select() d'éviterait de perdre du cpu pour rien, mais va falloir partir sur
des tutoriaux ou des bouquins, c'est trop long pour ici).
Ok je vais eplucher la doc de select();
Analogie: tu fais des frites chez McDo.
[...]
Bon, pas ma peine de me parler d'une facon aussi stupide, ce n'est
pas
parce-que je n'ecris pas tous les jours des softs de com que je suis
debile.
Je prefere largement que tu me parles avec des termes techniques,
meme
si apres je dois plonger dans la doc pour comprendre les informations.
(en fait, si ta communication est monodirectionnelle, tu n'as pas besoin d'avoir un flux
remontant
Non, la com entre les deux PC se fait bien dans les deux sens.
Le meme programme tourne sur les deux PC et chacun
peut prendre l'initiative d'envoyer des donees,
c'est pourquoi je pensais qu'il fallait deux sockets.
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Et on peut faire aussi bien du send() que du recv() dessus.
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Soit tu configures la socket en mode asynchrone et tu feras
un select() pour attendre qu'il y ait quelque chose à faire,
soit tu la laisses en mode synchrone et l'attente se fera
au sein du send() ou du recv().
L'immense intérêt du select(), c'est surtout quand tu
peux avoir plusieurs sources de données, par exemple le
clavier où tu tapes des commandes et une socket pour
envoyer et recevoir des données. Dans ce cas tu peux
configurer le tout en mode asynchrone, et tu fais un
select() sur l'ensemble des sockets et file descriptors.
Dès qu'il y a quelque chose à faire, le select() te rend
la main en te disant sur quoi il y a des choses à lire
(ou sur quoi tu peux écrire), et il n'y a plus qu'à le
faire. Si tu n'as qu'une seul socket et rien d'autre
à faire, alors pas besoin de select() : tu laisses la
socket en mode synchrone, et c'est elle qui bloquera
tant qu'il n'y a rien à lire ou que tu ne peux pas écrire.
Bien. Je ne te parlerai donc pas de façon stupide
pour te dire que Google groupes est une daube en tant
que nouvelleur : il vaudrait mieux utiliser un vrai
logiciel de nouvelles sur un vrai serveur NNTP.
Mais si vraiment tu ne peux pas faire autrement, alors
tu dois couper toi-même les lignes à une longueur plus
petite que la sienne, ou bien ne pas couper du tout
et le laisser faire. Parce que là, en coupant un tout
petit peu plus loin que Google groupes, ça fait une
alternance de lignes longues et de lignes courtes
qui est tout à fait insupportable.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
Bien sûr, si tu veux répondre « OK » à chaque
paquet reçu et que ça ne se mélange pas avec
les données que tu vas envoyer toi-même,
alors il faudra deux sockets,
mais tout semble indiquer que ces « OK » sont
inutiles si tu fais les choses comme il faut.
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Et on peut faire aussi bien du send() que du recv() dessus.
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Soit tu configures la socket en mode asynchrone et tu feras
un select() pour attendre qu'il y ait quelque chose à faire,
soit tu la laisses en mode synchrone et l'attente se fera
au sein du send() ou du recv().
L'immense intérêt du select(), c'est surtout quand tu
peux avoir plusieurs sources de données, par exemple le
clavier où tu tapes des commandes et une socket pour
envoyer et recevoir des données. Dans ce cas tu peux
configurer le tout en mode asynchrone, et tu fais un
select() sur l'ensemble des sockets et file descriptors.
Dès qu'il y a quelque chose à faire, le select() te rend
la main en te disant sur quoi il y a des choses à lire
(ou sur quoi tu peux écrire), et il n'y a plus qu'à le
faire. Si tu n'as qu'une seul socket et rien d'autre
à faire, alors pas besoin de select() : tu laisses la
socket en mode synchrone, et c'est elle qui bloquera
tant qu'il n'y a rien à lire ou que tu ne peux pas écrire.
Bien. Je ne te parlerai donc pas de façon stupide
pour te dire que Google groupes est une daube en tant
que nouvelleur : il vaudrait mieux utiliser un vrai
logiciel de nouvelles sur un vrai serveur NNTP.
Mais si vraiment tu ne peux pas faire autrement, alors
tu dois couper toi-même les lignes à une longueur plus
petite que la sienne, ou bien ne pas couper du tout
et le laisser faire. Parce que là, en coupant un tout
petit peu plus loin que Google groupes, ça fait une
alternance de lignes longues et de lignes courtes
qui est tout à fait insupportable.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
Bien sûr, si tu veux répondre « OK » à chaque
paquet reçu et que ça ne se mélange pas avec
les données que tu vas envoyer toi-même,
alors il faudra deux sockets,
mais tout semble indiquer que ces « OK » sont
inutiles si tu fais les choses comme il faut.
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Et on peut faire aussi bien du send() que du recv() dessus.
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Soit tu configures la socket en mode asynchrone et tu feras
un select() pour attendre qu'il y ait quelque chose à faire,
soit tu la laisses en mode synchrone et l'attente se fera
au sein du send() ou du recv().
L'immense intérêt du select(), c'est surtout quand tu
peux avoir plusieurs sources de données, par exemple le
clavier où tu tapes des commandes et une socket pour
envoyer et recevoir des données. Dans ce cas tu peux
configurer le tout en mode asynchrone, et tu fais un
select() sur l'ensemble des sockets et file descriptors.
Dès qu'il y a quelque chose à faire, le select() te rend
la main en te disant sur quoi il y a des choses à lire
(ou sur quoi tu peux écrire), et il n'y a plus qu'à le
faire. Si tu n'as qu'une seul socket et rien d'autre
à faire, alors pas besoin de select() : tu laisses la
socket en mode synchrone, et c'est elle qui bloquera
tant qu'il n'y a rien à lire ou que tu ne peux pas écrire.
Bien. Je ne te parlerai donc pas de façon stupide
pour te dire que Google groupes est une daube en tant
que nouvelleur : il vaudrait mieux utiliser un vrai
logiciel de nouvelles sur un vrai serveur NNTP.
Mais si vraiment tu ne peux pas faire autrement, alors
tu dois couper toi-même les lignes à une longueur plus
petite que la sienne, ou bien ne pas couper du tout
et le laisser faire. Parce que là, en coupant un tout
petit peu plus loin que Google groupes, ça fait une
alternance de lignes longues et de lignes courtes
qui est tout à fait insupportable.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
Bien sûr, si tu veux répondre « OK » à chaque
paquet reçu et que ça ne se mélange pas avec
les données que tu vas envoyer toi-même,
alors il faudra deux sockets,
mais tout semble indiquer que ces « OK » sont
inutiles si tu fais les choses comme il faut.
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
celui-ci peut connaitre les IP:PORT de l'emetteur ?
Et on peut faire aussi bien du send() que du recv() dessus.
En meme temps ?
Est-ce qu'au meme instant, une meme socket peut etre
en cours de reception de donnees dans une thread,
et en cours d'emission dans une autre ?
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Mais heureusement, une fois les modifs faites,
ces ACK n'auront plus aucune raison d'etre.
Etre bloquant en emission serait parfait, mais pas en
reception, car c'est justement parce-que la fonction
accept() est bloquante que j'ai du la faire tourner
dans une thread distincte de celle du traitement
des messages Windows (sinon ca freeze la fenetre)
D'autre part il est necessaire de pouvoir envoyer
tout en etant en etat "listen" pour la reception.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
N'importe quel PC peut prendre
l'initiative d'envoyer des donnees ?
Je me pose une autre question :
Soient deux PC "A" et "B" faisant tourner le meme soft,
"A" connait l'IP de "B" et etablit la com entre eux :
est-ce que cela ne signifie pas qu'il y a un serveur
et un client, et par suite, une certaine asymetrie ?
Une fois la connection etablie, est-ce que cela permet
tout de meme a n'importe quel des deux PC de prendre
l'initiative d'envoyer des donnees a l'autre ?
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
celui-ci peut connaitre les IP:PORT de l'emetteur ?
Et on peut faire aussi bien du send() que du recv() dessus.
En meme temps ?
Est-ce qu'au meme instant, une meme socket peut etre
en cours de reception de donnees dans une thread,
et en cours d'emission dans une autre ?
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Mais heureusement, une fois les modifs faites,
ces ACK n'auront plus aucune raison d'etre.
Etre bloquant en emission serait parfait, mais pas en
reception, car c'est justement parce-que la fonction
accept() est bloquante que j'ai du la faire tourner
dans une thread distincte de celle du traitement
des messages Windows (sinon ca freeze la fenetre)
D'autre part il est necessaire de pouvoir envoyer
tout en etant en etat "listen" pour la reception.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
N'importe quel PC peut prendre
l'initiative d'envoyer des donnees ?
Je me pose une autre question :
Soient deux PC "A" et "B" faisant tourner le meme soft,
"A" connait l'IP de "B" et etablit la com entre eux :
est-ce que cela ne signifie pas qu'il y a un serveur
et un client, et par suite, une certaine asymetrie ?
Une fois la connection etablie, est-ce que cela permet
tout de meme a n'importe quel des deux PC de prendre
l'initiative d'envoyer des donnees a l'autre ?
Une socket en mode connecté (TCP) contient à la fois les
deux adresses et les deux ports (« local » et « remote »).
Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
celui-ci peut connaitre les IP:PORT de l'emetteur ?
Et on peut faire aussi bien du send() que du recv() dessus.
En meme temps ?
Est-ce qu'au meme instant, une meme socket peut etre
en cours de reception de donnees dans une thread,
et en cours d'emission dans une autre ?
Au passage, si les deux côtés émettent en même temps,
chacun peut profiter de son envoi de données pour accuser
réception du dernier paquet reçu (« ACK »), ce qui peut
diviser par deux le nombre de paquets échangés.
Mais heureusement, une fois les modifs faites,
ces ACK n'auront plus aucune raison d'etre.
Etre bloquant en emission serait parfait, mais pas en
reception, car c'est justement parce-que la fonction
accept() est bloquante que j'ai du la faire tourner
dans une thread distincte de celle du traitement
des messages Windows (sinon ca freeze la fenetre)
D'autre part il est necessaire de pouvoir envoyer
tout en etant en etat "listen" pour la reception.
À partir du moment où la connexion est établie,
ce quel qu'en soit l'initiateur, la socket
est parfaitement symétrique.
N'importe quel PC peut prendre
l'initiative d'envoyer des donnees ?
Je me pose une autre question :
Soient deux PC "A" et "B" faisant tourner le meme soft,
"A" connait l'IP de "B" et etablit la com entre eux :
est-ce que cela ne signifie pas qu'il y a un serveur
et un client, et par suite, une certaine asymetrie ?
Une fois la connection etablie, est-ce que cela permet
tout de meme a n'importe quel des deux PC de prendre
l'initiative d'envoyer des donnees a l'autre ?
> Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
> celui-ci peut connaitre les IP:PORT de l'emetteur ?
Même *avant* qu'il ait effectivement reçu des données !
L'information se trouve dans le résultat de la fonction
accept(). Par ailleurs tu peux aussi retrouver cette
info par getpeername() (IP et port distants)
et getsockname() (IP et port locaux).
> Est-ce qu'au meme instant, une meme socket peut etre
> en cours de reception de donnees dans une thread,
> et en cours d'emission dans une autre ?
En principe oui, d'autant que les fonctions send()
et recv() travaillent sur des buffers internes,
et pas sur l'envoi de trames ethernet !
Problème de vocabulaire ici : je parlais du ACK des
trames TCP, pas des «OK» que tu avais rajoutés !
Les ACK au niveau TCP ont bien sûr toujours lieu d'être,
et si l'échange est bidirectionnel chaque paquet envoyé
d'un côté peut servir de ACK à un paquet envoyé de l'autre.
Si l'échange n'est que dans un seul sens, alors des ACK
seront envoyés quand même, sans données.
> Etre bloquant en emission serait parfait, mais pas en
> reception, car c'est justement parce-que la fonction
> accept() est bloquante que j'ai du la faire tourner
> dans une thread distincte de celle du traitement
> des messages Windows (sinon ca freeze la fenetre)
> D'autre part il est necessaire de pouvoir envoyer
> tout en etant en etat "listen" pour la reception.
Avec des sockets asynchrones et la fonction select(),
il n'y a pas besoin de plusieurs threads.
> N'importe quel PC peut prendre
> l'initiative d'envoyer des donnees ?
Oui, absolument. Une fois la connexion établie,
on ne peut plus savoir qui l'a établie :
la socket est vraiment symétrique.
> Soient deux PC "A" et "B" faisant tourner le meme soft,
> "A" connait l'IP de "B" et etablit la com entre eux :
> est-ce que cela ne signifie pas qu'il y a un serveur
> et un client, et par suite, une certaine asymetrie ?
L'asymétrie existe à la connexion uniquement. Et encore,
on pourrait très bien imaginer que chacun soit serveur
et se mette en attente d'une nouvelle connexion par
accept(), puis que le premier à avoir des données à
transmettre fasse le connect(). Une fois la connexion
établie, chacun peut l'utiliser à sa guise.
> Une fois la connection etablie, est-ce que cela permet
> tout de meme a n'importe quel des deux PC de prendre
> l'initiative d'envoyer des donnees a l'autre ?
Oui.
> Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
> celui-ci peut connaitre les IP:PORT de l'emetteur ?
Même *avant* qu'il ait effectivement reçu des données !
L'information se trouve dans le résultat de la fonction
accept(). Par ailleurs tu peux aussi retrouver cette
info par getpeername() (IP et port distants)
et getsockname() (IP et port locaux).
> Est-ce qu'au meme instant, une meme socket peut etre
> en cours de reception de donnees dans une thread,
> et en cours d'emission dans une autre ?
En principe oui, d'autant que les fonctions send()
et recv() travaillent sur des buffers internes,
et pas sur l'envoi de trames ethernet !
Problème de vocabulaire ici : je parlais du ACK des
trames TCP, pas des «OK» que tu avais rajoutés !
Les ACK au niveau TCP ont bien sûr toujours lieu d'être,
et si l'échange est bidirectionnel chaque paquet envoyé
d'un côté peut servir de ACK à un paquet envoyé de l'autre.
Si l'échange n'est que dans un seul sens, alors des ACK
seront envoyés quand même, sans données.
> Etre bloquant en emission serait parfait, mais pas en
> reception, car c'est justement parce-que la fonction
> accept() est bloquante que j'ai du la faire tourner
> dans une thread distincte de celle du traitement
> des messages Windows (sinon ca freeze la fenetre)
> D'autre part il est necessaire de pouvoir envoyer
> tout en etant en etat "listen" pour la reception.
Avec des sockets asynchrones et la fonction select(),
il n'y a pas besoin de plusieurs threads.
> N'importe quel PC peut prendre
> l'initiative d'envoyer des donnees ?
Oui, absolument. Une fois la connexion établie,
on ne peut plus savoir qui l'a établie :
la socket est vraiment symétrique.
> Soient deux PC "A" et "B" faisant tourner le meme soft,
> "A" connait l'IP de "B" et etablit la com entre eux :
> est-ce que cela ne signifie pas qu'il y a un serveur
> et un client, et par suite, une certaine asymetrie ?
L'asymétrie existe à la connexion uniquement. Et encore,
on pourrait très bien imaginer que chacun soit serveur
et se mette en attente d'une nouvelle connexion par
accept(), puis que le premier à avoir des données à
transmettre fasse le connect(). Une fois la connexion
établie, chacun peut l'utiliser à sa guise.
> Une fois la connection etablie, est-ce que cela permet
> tout de meme a n'importe quel des deux PC de prendre
> l'initiative d'envoyer des donnees a l'autre ?
Oui.
> Ok. Je suppose qu'apres qu'un PC ait recu des donnees,
> celui-ci peut connaitre les IP:PORT de l'emetteur ?
Même *avant* qu'il ait effectivement reçu des données !
L'information se trouve dans le résultat de la fonction
accept(). Par ailleurs tu peux aussi retrouver cette
info par getpeername() (IP et port distants)
et getsockname() (IP et port locaux).
> Est-ce qu'au meme instant, une meme socket peut etre
> en cours de reception de donnees dans une thread,
> et en cours d'emission dans une autre ?
En principe oui, d'autant que les fonctions send()
et recv() travaillent sur des buffers internes,
et pas sur l'envoi de trames ethernet !
Problème de vocabulaire ici : je parlais du ACK des
trames TCP, pas des «OK» que tu avais rajoutés !
Les ACK au niveau TCP ont bien sûr toujours lieu d'être,
et si l'échange est bidirectionnel chaque paquet envoyé
d'un côté peut servir de ACK à un paquet envoyé de l'autre.
Si l'échange n'est que dans un seul sens, alors des ACK
seront envoyés quand même, sans données.
> Etre bloquant en emission serait parfait, mais pas en
> reception, car c'est justement parce-que la fonction
> accept() est bloquante que j'ai du la faire tourner
> dans une thread distincte de celle du traitement
> des messages Windows (sinon ca freeze la fenetre)
> D'autre part il est necessaire de pouvoir envoyer
> tout en etant en etat "listen" pour la reception.
Avec des sockets asynchrones et la fonction select(),
il n'y a pas besoin de plusieurs threads.
> N'importe quel PC peut prendre
> l'initiative d'envoyer des donnees ?
Oui, absolument. Une fois la connexion établie,
on ne peut plus savoir qui l'a établie :
la socket est vraiment symétrique.
> Soient deux PC "A" et "B" faisant tourner le meme soft,
> "A" connait l'IP de "B" et etablit la com entre eux :
> est-ce que cela ne signifie pas qu'il y a un serveur
> et un client, et par suite, une certaine asymetrie ?
L'asymétrie existe à la connexion uniquement. Et encore,
on pourrait très bien imaginer que chacun soit serveur
et se mette en attente d'une nouvelle connexion par
accept(), puis que le premier à avoir des données à
transmettre fasse le connect(). Une fois la connexion
établie, chacun peut l'utiliser à sa guise.
> Une fois la connection etablie, est-ce que cela permet
> tout de meme a n'importe quel des deux PC de prendre
> l'initiative d'envoyer des donnees a l'autre ?
Oui.