Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Jean-Christophe a écrit :Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Je ne comprend pas à quel niveau tu te situe avec ton soft. Tu ouvres un
socket tcp en te basant sur des appels système ou tu refais le TCP en
utilisant la couche IP ? Parce que je ne vois pas de raisons de perdre
des paquets en TCP.
Jean-Christophe a écrit :
Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Je ne comprend pas à quel niveau tu te situe avec ton soft. Tu ouvres un
socket tcp en te basant sur des appels système ou tu refais le TCP en
utilisant la couche IP ? Parce que je ne vois pas de raisons de perdre
des paquets en TCP.
Jean-Christophe a écrit :Avec un soft maison qui utilise winsock2, je teste une com en TCP
entre deux PC sous XP, et en local via Ethernet ca marche a 100 %.
Par contre via Internet entre deux PC (distants de 500 km)
il y a des pertes de quelques %.
Ca reste faible et j'ai une couche soft qui s'occuppe des time-out
et des retry, donc l'ensemble fonctionne comme il faut.
Mais je ne comprends pas la raison pour laquelle des paquets
envoyes n'arrivent pas a destination: est-ce qu'en mode
TCP le transport ne garantit pas la livraison des paquets ?
Je ne comprend pas à quel niveau tu te situe avec ton soft. Tu ouvres un
socket tcp en te basant sur des appels système ou tu refais le TCP en
utilisant la couche IP ? Parce que je ne vois pas de raisons de perdre
des paquets en TCP.
si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux
(surtout si les FAI sont différents).
si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux
(surtout si les FAI sont différents).
si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux
(surtout si les FAI sont différents).
Tu ouvres un socket tcp en te basant sur des appels système
ou tu refais le TCP en utilisant la couche IP ?
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Tu ouvres un socket tcp en te basant sur des appels système
ou tu refais le TCP en utilisant la couche IP ?
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Tu ouvres un socket tcp en te basant sur des appels système
ou tu refais le TCP en utilisant la couche IP ?
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Surtout qu'au niveau TCP, c'est un double flux d'octets, pas des paquets, qui est géré.
Maintenant, réimplémenter des time-out & retry au dessus de TCP me pa rait bizarre.
"A la place" au lieu de "au dessus" ?
Ou alors c'est pas du TCP ?
Ou bien le soft réfait TCP lui-même, et donc fait des paquets IP ?
TCP, c'est du transport, de bout en bout: C'est les extrémités qui v érifient et
s'organisent si il y a des pertes. Les intermédiaires n'en ont rien à cirer que la
communication soit TCP ou autres (sauf les NAT/firewall...) et ne voient que des paquets
IP, potentiellement dans le désordre, et pas forcément tous ceux de l a connexion.
Et puis 500 km, c'est à vol d'oiseau... si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux (surtout si les FAI sont différents).
Surtout qu'au niveau TCP, c'est un double flux d'octets, pas des paquets, qui est géré.
Maintenant, réimplémenter des time-out & retry au dessus de TCP me pa rait bizarre.
"A la place" au lieu de "au dessus" ?
Ou alors c'est pas du TCP ?
Ou bien le soft réfait TCP lui-même, et donc fait des paquets IP ?
TCP, c'est du transport, de bout en bout: C'est les extrémités qui v érifient et
s'organisent si il y a des pertes. Les intermédiaires n'en ont rien à cirer que la
communication soit TCP ou autres (sauf les NAT/firewall...) et ne voient que des paquets
IP, potentiellement dans le désordre, et pas forcément tous ceux de l a connexion.
Et puis 500 km, c'est à vol d'oiseau... si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux (surtout si les FAI sont différents).
Surtout qu'au niveau TCP, c'est un double flux d'octets, pas des paquets, qui est géré.
Maintenant, réimplémenter des time-out & retry au dessus de TCP me pa rait bizarre.
"A la place" au lieu de "au dessus" ?
Ou alors c'est pas du TCP ?
Ou bien le soft réfait TCP lui-même, et donc fait des paquets IP ?
TCP, c'est du transport, de bout en bout: C'est les extrémités qui v érifient et
s'organisent si il y a des pertes. Les intermédiaires n'en ont rien à cirer que la
communication soit TCP ou autres (sauf les NAT/firewall...) et ne voient que des paquets
IP, potentiellement dans le désordre, et pas forcément tous ceux de l a connexion.
Et puis 500 km, c'est à vol d'oiseau... si ça se trouve, les paquets vont se balader en
norvège, passe par Dallas puis reviennent par Bordeaux (surtout si les FAI sont différents).
On Jul 29, 6:56 pm, GuiGui
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
On Jul 29, 6:56 pm, GuiGui <Gui...@nospam.fr>
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
On Jul 29, 6:56 pm, GuiGui
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
Le 29/07/2009 22:52, Jean-Christophe nous fit lire :On Jul 29, 6:56 pm, GuiGui
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en protocol, c'est bien
ça ?Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations fassent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements différents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement délimités dans le flux d'octets que tu
émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close" (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windows que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'application,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmission, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot, c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TCP n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une nouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission, donc quand tu demandes à
envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à cause du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée. En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont le buffer n'est
JAMAIS infini).
Le 29/07/2009 22:52, Jean-Christophe nous fit lire :
On Jul 29, 6:56 pm, GuiGui <Gui...@nospam.fr>
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en protocol, c'est bien
ça ?
Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations fassent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements différents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement délimités dans le flux d'octets que tu
émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close" (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windows que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'application,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?
Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmission, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot, c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TCP n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?
Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une nouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission, donc quand tu demandes à
envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à cause du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée. En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont le buffer n'est
JAMAIS infini).
Le 29/07/2009 22:52, Jean-Christophe nous fit lire :On Jul 29, 6:56 pm, GuiGui
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en protocol, c'est bien
ça ?Parce que je ne vois pas de raisons de perdre des paquets en TCP.
Moi non plus.
Tout marche sans aucun probleme a 100 % en local sous Ethernet
(un LAN avec juste un routeur entre les deux machines)
les donnees envoyees sont toujours recues, et dans les deux sens,
alors pour moi ca valide le code de mon programme de com.
Par Internet ca fonctionne, mais il arrive, bien que ce
soit rare donc pas genant en pratique, que quelquefois des
donnees envoyees par send() ne soient pas recues (par recv)
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations fassent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements différents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement délimités dans le flux d'octets que tu
émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close" (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windows que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'application,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?Et c'est lorsque j'ai constate cela que j'ai implemente un handshake
avec timeout et renvoi des donnees en cas de non-reception d'un ACK.
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmission, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot, c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TCP n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?Mais je ne m'y attendais pas du tout : j'ai toujours lu partout
que la couche TCP garantit que les donnees soient delivrees.
Des idees ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une nouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission, donc quand tu demandes à
envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à cause du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée. En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont le buffer n'est
JAMAIS infini).
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en pro tocol,
c'est bien ça ?
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations f assent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements d ifférents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement
délimités dans le flux d'octets que tu émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close " (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windo ws que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'ap plication,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmi ssion, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot , c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TC P n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une n ouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission,
donc quand tu demandes à envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à ca use du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée.
En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont l e buffer n'est
JAMAIS infini).
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en pro tocol,
c'est bien ça ?
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations f assent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements d ifférents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement
délimités dans le flux d'octets que tu émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close " (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windo ws que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'ap plication,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmi ssion, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot , c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TC P n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une n ouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission,
donc quand tu demandes à envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à ca use du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée.
En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont l e buffer n'est
JAMAIS infini).
socket(), avec AF_INET (ou PF_INET), SOCK_STREAM et probablement 0 en pro tocol,
c'est bien ça ?
Attention, il n'y a pas forcément un recv par send avec TCP.
Sur un lan, il est possible que les temps de réponses et propagations f assent que chaque
bloc survive à la traversé.
Au travers d'un réseau plus complexe, on peut avoir des comportements d ifférents:
aggrégation de données retransmises, fermeture de fenêtres...
J'espère que tes données/messages sont correctement
délimités dans le flux d'octets que tu émets et reçoit.
Un truc quand même: la séquence "socket-bind-listen-accept" et "close " (d'ailleurs,
pourquoi closesocket ? normalement c'est close()... particularité windo ws que je ne
connais pas ?) n'a bien lieu qu'une seule fois, dans toute la vie de l'ap plication,
n'est-ce pas ?
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message" a
traité, si ?
Et là, j'ai l'impression qu'au lieu d'attendre normalement la retransmi ssion, ton appli
s'impatiente et court-circuite la marche normale (et c'est pas son boulot , c'est celui du
transport, en l'occurence TCP; Si tu as des besoins de réactivité, TC P n'est pas le bon
transport).
Et je m'interroge, comment l'autre coté gère la réception en double des messages ?
Bref, peux-tu détailler comment tu renvoies les données ?
Juste une angoisse: pour chaque "échange", ton architecture ouvre une n ouvelle connexion.
Ou bien... tu ne regardes pas le retour de send().
Il renvoie le nombre d'octets envoyés.
Sur un Lan, il épuise difficilement la fenêtre de transmission,
donc quand tu demandes à envoyer 2000 octets, il réussit.
Au travers d'Internet... la fenêtre est beaucoup plus occupée (à ca use du temps de
traversée), il peut donc n'en envoyer que 1700 (par exemple)... d'où des "paquets" qui te
manque à l'arrivée.
En fait, ils ne sont jamais partis, et c'est ta faute.
send() t'a répondu 1700... c'était à toi de revenir plus tard pour les 300 restants.
Je m'étonne d'ailleurs que tu n'ai pas de select() dans tes fonctions. (ne serait-ce que
pour savoir quand il redevient possible d'écrire dans la socket, dont l e buffer n'est
JAMAIS infini).
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message"
[à traiter], si ?
[...]
En gros ca se passe comme ca :
A envoie un bloc de donnees vers B.
Si B recoit il renvoie "OK" vers A, qui envoie le bloc de donnees
suivant.
Si B ne recoit pas le timeout tombe en A, qui renvoie le meme bloc de
donnees.
Tout cela me donne une com a 100 % via internet.
[...]
/*--------------------------------------------------------------
Fonction d'emission
*ptr : pointeur sur les donnees
len : taille des donnees
--------------------------------------------------------------*/
int fSendBuffer(char *ptr, int len)
{
int nb; // util
// sock
if( fSetTxSock(1) ) // ouverture
return 1; // fatal error
// send loop
while( len > 0 )
{
// envoi du bloc courant
nb = send(ServParam.tx_socket,ptr,len,0); // envoi
// check
if( nb == SOCKET_ERROR ) // erreur
{
fSetTxSock(0); // on ferme
return 2; // fatal error
}
[...]
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message"
[à traiter], si ?
[...]
En gros ca se passe comme ca :
A envoie un bloc de donnees vers B.
Si B recoit il renvoie "OK" vers A, qui envoie le bloc de donnees
suivant.
Si B ne recoit pas le timeout tombe en A, qui renvoie le meme bloc de
donnees.
Tout cela me donne une com a 100 % via internet.
[...]
/*--------------------------------------------------------------
Fonction d'emission
*ptr : pointeur sur les donnees
len : taille des donnees
--------------------------------------------------------------*/
int fSendBuffer(char *ptr, int len)
{
int nb; // util
// sock
if( fSetTxSock(1) ) // ouverture
return 1; // fatal error
// send loop
while( len > 0 )
{
// envoi du bloc courant
nb = send(ServParam.tx_socket,ptr,len,0); // envoi
// check
if( nb == SOCKET_ERROR ) // erreur
{
fSetTxSock(0); // on ferme
return 2; // fatal error
}
[...]
on n'est pas dans le cas d'un client qui ouvre une connexion pour chaque "message"
[à traiter], si ?
[...]
En gros ca se passe comme ca :
A envoie un bloc de donnees vers B.
Si B recoit il renvoie "OK" vers A, qui envoie le bloc de donnees
suivant.
Si B ne recoit pas le timeout tombe en A, qui renvoie le meme bloc de
donnees.
Tout cela me donne une com a 100 % via internet.
[...]
/*--------------------------------------------------------------
Fonction d'emission
*ptr : pointeur sur les donnees
len : taille des donnees
--------------------------------------------------------------*/
int fSendBuffer(char *ptr, int len)
{
int nb; // util
// sock
if( fSetTxSock(1) ) // ouverture
return 1; // fatal error
// send loop
while( len > 0 )
{
// envoi du bloc courant
nb = send(ServParam.tx_socket,ptr,len,0); // envoi
// check
if( nb == SOCKET_ERROR ) // erreur
{
fSetTxSock(0); // on ferme
return 2; // fatal error
}
[...]
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.
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qu i
plus est, tu commences par fermer la précédente : t'es-tu assuré qu e
tout avait été envoyé ?
> if( nb == SOCKET_ERROR ) // erreur
Je suppose que SOCKET_ERROR vaut -1. Personnellement j'ai l'habitude
d'écrire plutôt « (nb < 0) » que « (nb == -1) », mais d'a près le man ça
devrait être équivalent.
Tu n'as pas vérifié le code contenu dans errno. Selon le cas cela
pourrait ne *pas* être une erreur fatale, par exemple EAGAIN ou
EWOULDBLOCK pour une socket non bloquante (ce qui ne semble pas être
le cas)
ou encore EINTR si un signal a été reçu.
Dans ce cas il faut continuer à envoyer la suite.
Ah, une recherche dans MSDN m'indique que c'est WSAGetLastError() au
lieu de errno, WSAEWOULDBLOCK au lieu de EWOULDBLOCK et WSAEINTR au lieu
de EINTR, mais la remarque reste valable.
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.
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qu i
plus est, tu commences par fermer la précédente : t'es-tu assuré qu e
tout avait été envoyé ?
> if( nb == SOCKET_ERROR ) // erreur
Je suppose que SOCKET_ERROR vaut -1. Personnellement j'ai l'habitude
d'écrire plutôt « (nb < 0) » que « (nb == -1) », mais d'a près le man ça
devrait être équivalent.
Tu n'as pas vérifié le code contenu dans errno. Selon le cas cela
pourrait ne *pas* être une erreur fatale, par exemple EAGAIN ou
EWOULDBLOCK pour une socket non bloquante (ce qui ne semble pas être
le cas)
ou encore EINTR si un signal a été reçu.
Dans ce cas il faut continuer à envoyer la suite.
Ah, une recherche dans MSDN m'indique que c'est WSAGetLastError() au
lieu de errno, WSAEWOULDBLOCK au lieu de EWOULDBLOCK et WSAEINTR au lieu
de EINTR, mais la remarque reste valable.
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.
Donc en effet tu ouvres une nouvelle connexion à chaque fSendBuffer. Qu i
plus est, tu commences par fermer la précédente : t'es-tu assuré qu e
tout avait été envoyé ?
> if( nb == SOCKET_ERROR ) // erreur
Je suppose que SOCKET_ERROR vaut -1. Personnellement j'ai l'habitude
d'écrire plutôt « (nb < 0) » que « (nb == -1) », mais d'a près le man ça
devrait être équivalent.
Tu n'as pas vérifié le code contenu dans errno. Selon le cas cela
pourrait ne *pas* être une erreur fatale, par exemple EAGAIN ou
EWOULDBLOCK pour une socket non bloquante (ce qui ne semble pas être
le cas)
ou encore EINTR si un signal a été reçu.
Dans ce cas il faut continuer à envoyer la suite.
Ah, une recherche dans MSDN m'indique que c'est WSAGetLastError() au
lieu de errno, WSAEWOULDBLOCK au lieu de EWOULDBLOCK et WSAEINTR au lieu
de EINTR, mais la remarque reste valable.