Liaison TCPIP décalage de réception
robunccm
Messages postés
53
Date d'inscription
Statut
Membre
Dernière intervention
-
Utilisateur anonyme -
Utilisateur anonyme -
Bonsoir à tous, j'en appelle une fois de plus à vos lumières pour tenter d'y voir plus clair.
Merci par avance.
Le contexte Un PC dialogue avec un Arduino via Ethernet.
Dans un premier temps le principe est plutôt simple.
Le PC envoi un ordre, l'Arduino retourne instantanément cet ordre en le complétant de diverses data.
Mon problème je ne reçoit
le retour de l'ordre 1 qu'après l'envoi de l'ordre 2,
le retour de l'ordre 2 qu'après l'envoi de l'ordre 3
et ainsi de suite.
Je n'ose pas vous dire le nombre de variante essayées mais sans succès!
Ce doit être gros comme une porte de grange mais je bute.
Merci de votre aide
Roland dit Le chef de gare
Déclaration data
Ouverture d'un socket
Méthode Write et Read
Merci par avance.
Le contexte Un PC dialogue avec un Arduino via Ethernet.
Dans un premier temps le principe est plutôt simple.
Le PC envoi un ordre, l'Arduino retourne instantanément cet ordre en le complétant de diverses data.
Mon problème je ne reçoit
le retour de l'ordre 1 qu'après l'envoi de l'ordre 2,
le retour de l'ordre 2 qu'après l'envoi de l'ordre 3
et ainsi de suite.
Je n'ose pas vous dire le nombre de variante essayées mais sans succès!
Ce doit être gros comme une porte de grange mais je bute.
Merci de votre aide
Roland dit Le chef de gare
Déclaration data
private TcpClient clientSocket17x = new TcpClient();
Ouverture d'un socket
private void TryConnectClient(int _numARD)
{
try
{
string AdresseIP = "192.168.1." + Convert.ToString(ArdNum);
clientSocket17x.Connect(AdresseIP, 8000 + _numARD);
clientSocket17x.ReceiveBufferSize = 50;
//clientSocket17x.ReceiveTimeout = 5000;
}
catch (Exception exception)
{ MessageBox.Show("Rob Try ConnectClient" + exception.Message); }
}
Méthode Write et Read
public void SendOrder(string Order)
{
NetworkStream serverStream = clientSocket17x.GetStream();
serverStream.Flush();
TxtLine2 = Order;
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(Order + "\n");
serverStream.Write(buffer, 0, buffer.Length);
serverStream.Flush();
Int32 cpt = 0;
String rep = "";
if (serverStream.DataAvailable)
{
serverStream.Read(inStream, 0, clientSocket17x.ReceiveBufferSize);
string returndata = Encoding.ASCII.GetString(inStream);
TxtLine3 = returndata;
}
}
Configuration: Windows / Chrome 96.0.4664.45
A voir également:
- Liaison TCPIP décalage de réception
- Accusé de reception gmail - Guide
- Problème de réception tv pas de signal aujourd' hui - Guide
- Serveur de reception mail - Guide
- Hotmail boîte de réception - Guide
- Accusé de reception outlook - Guide
3 réponses
Bonsoir
La seul fois où j'ai codé une liaison TCP, c'était dans un cadre particulier où il fallait utiliser une classe métier particulière (et donc pas TcpClient).
Mais en UDP et cette fois là, le dialogue n'est pas instantané.
Là comme je lis ton code (je me trompe peut-être), il faudrait que ça le soit, tu cherches à lire la réponse sans même attendre qu'elle soit arrivé.
Tu pourrais peut-être faire une boucle le temps que serverStream.DataAvailable passe à true (avec un nombre max de boucle sinon en cas de coupure de liaison ça fera une boucle infinie).
Ça va figer ton thread, mais ça permettra de voir si mon hypothèse est juste.
Un truc du genre
En plus, tu te sers 2 fois de la méthode Flush(), dans les exemples que j'ai trouvé, cette méthode n'est pas utilisée.
La seul fois où j'ai codé une liaison TCP, c'était dans un cadre particulier où il fallait utiliser une classe métier particulière (et donc pas TcpClient).
Mais en UDP et cette fois là, le dialogue n'est pas instantané.
Là comme je lis ton code (je me trompe peut-être), il faudrait que ça le soit, tu cherches à lire la réponse sans même attendre qu'elle soit arrivé.
Tu pourrais peut-être faire une boucle le temps que serverStream.DataAvailable passe à true (avec un nombre max de boucle sinon en cas de coupure de liaison ça fera une boucle infinie).
Ça va figer ton thread, mais ça permettra de voir si mon hypothèse est juste.
Un truc du genre
for(int i = 0; i < 1000; i++) { if(serverStream.DataAvailable) break; Thread.Sleep(1); }
En plus, tu te sers 2 fois de la méthode Flush(), dans les exemples que j'ai trouvé, cette méthode n'est pas utilisée.
C'est cool que tu aies trouvé.
Je ne pensais pas que Write était synchrone....
Pour éviter que ta fenêtre fige, tu peux mettre ce code dans un thread.
A la fin, il faut que tu signales que c'est fini, avec un évènement par exemple
Je ne pensais pas que Write était synchrone....
Pour éviter que ta fenêtre fige, tu peux mettre ce code dans un thread.
A la fin, il faut que tu signales que c'est fini, avec un évènement par exemple
Bonjour à tous et à Whismeril en particulier car fidèle à l'écoute de mes questions, merci une nouvelle fois.
Toutefois la proposition n'a pas fonctionné mais comme souvent elle m'a conduit d'autres test qui ont aboutis.
En réalité le problème se situait du coté Arduino qui construisait mal la réponse.
Voici le code finalement utilisé et sans doute perfectible.
Pour ce que j'en comprends.
Ce code gère une liaison dite bloquante ou synchrone, serverStream.Write se charge de l'envoi du message, dès l'envoi de celui-ci le processus se met en écoute et serverStream informé par serverStream.DataAvailable.Read se charge de la lecture de la réponse. On ne peut donc pas la manquer le problème est que si il n'y a pas de réponse le système attend indéfiniment. Il existe une possibilité de TimeOut.
Par ailleurs une alternative dite asynchrone évite le blocage, à priori elle est plus complexe . Mais à vaincre sans péril on triomphe sans gloire ... donc à bientôt pour le prochain épisode.
Roland
Toutefois la proposition n'a pas fonctionné mais comme souvent elle m'a conduit d'autres test qui ont aboutis.
En réalité le problème se situait du coté Arduino qui construisait mal la réponse.
Voici le code finalement utilisé et sans doute perfectible.
Pour ce que j'en comprends.
Ce code gère une liaison dite bloquante ou synchrone, serverStream.Write se charge de l'envoi du message, dès l'envoi de celui-ci le processus se met en écoute et serverStream informé par serverStream.DataAvailable.Read se charge de la lecture de la réponse. On ne peut donc pas la manquer le problème est que si il n'y a pas de réponse le système attend indéfiniment. Il existe une possibilité de TimeOut.
Par ailleurs une alternative dite asynchrone évite le blocage, à priori elle est plus complexe . Mais à vaincre sans péril on triomphe sans gloire ... donc à bientôt pour le prochain épisode.
Roland
public void SendOrder(string Order)
{
NetworkStream serverStream = clientSocket17x.GetStream();
TxtLine2 = Order;
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(Order + "\n");
serverStream.Write(buffer, 0, buffer.Length);
if (serverStream.CanRead)
{
byte[] myReadBuffer = new byte[1024];
StringBuilder myCompleteMessage = new StringBuilder();
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = serverStream.Read(myReadBuffer, 0, myReadBuffer.Length);
myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
}
while (serverStream.DataAvailable);
TxtLine3 = (myCompleteMessage.ToString());
}
else
{
TxtLine3 = ("Sorry. You cannot read from this NetworkStream.");
}
}
Quant à la méthode Flush il semble qu'elle ne soit pas encore implémentée et ne servirait à rien.
Je teste et je t'informe. En tout merci.