Problème Vb.Net TCP/IP - C#/.NET managed - Programmation
Marsh Posté le 09-08-2007 à 13:18:17
de 1, je te conseille de te documenter directement sur le lecteur. Il doit surement y avoir quelques part une doc expliquant comment celui ci fonctionne et quel message il peut recevoir/envoyer...
ensuite, ce qui me gène un peu, c'est que tu veux gérer toi même les numéro de séquence et les numéro ack.
Or si tu es bien en TCP/IP, c'est le protocole qui se charge de faire cela pour toi...
Par contre, si tu es en UDP, c'est à toi de gérer cela...
Visisblement, tu es bien en TCP... donc tu ne dois pas t'en préoccuper.
Maintenant, si tu as réussi à sniffer les paquets initiaux avec l'ancien programme, tu dois pouvoir les analyser plus précisement et comprendre peut être pourquoi ton lecteur ne réagi pas.
Marsh Posté le 09-08-2007 à 13:33:03
moi23372 a écrit : de 1, je te conseille de te documenter directement sur le lecteur. Il doit surement y avoir quelques part une doc expliquant comment celui ci fonctionne et quel message il peut recevoir/envoyer... |
Ben justement, je ne comprends pas.
Pour répondre à ton 1, je n'ai pas trouvé de doc. J'ai une doc donnée lors de l'achat de la machine et du logiciel gestionnaire mais rien sur la communication. J'ai piétinné sur ce point, et c'est pour ça que j'ai cherché à sniffer.
Et dans les sniffs, rien de plus que ce que j'ai expliqué, à moins que je devienne aveugle (je peux éventuellement poster des logs de sniffs si qqn veut).
Je ne veux pas forcément les gérer, mais j'aimerais déjà savoir si le fonctionnement que j'ai décrit est normal...
Merci
Marsh Posté le 16-08-2007 à 08:51:07
Après une longue période d'analyse, j'ai enfin trouvé mon problème.
Mon application, en fait, n'a pas de problème au niveau TCP/IP.
Mon serveur reçoit correctement les messages, et répond correctement (enfin presque).
Pour rappel, mon code fonctionne de la façon suivante :
Code :
|
Donc, entre l'arrêt et le redémarrage de l'écoute, le serveur est sourd. Le problème, c'est que le client n'est pas muet de son coté, et il envoie, dans ce laps de temps, d'autres paquets, qui sont donc perdus.
Dans les logs du sniff que j'ai fait, j'ai donc des packet loss, et des questions sans réponses (pour le client).
C'est pour ça que la communication n'est pas complète.
Alors je cherche un peu partout sur le net une façon d'arrêter l'écoute, puis de la reprendre immédiatement (l'arrêt de l'écoute est obligatoire avec ces méthodes asynchrones).
J'ai essayé pas mal de choses : relancer l'écoute avant le traitement de la réponse, relancer l'écoute dans un thread que je créée manuellement, etc etc...
Si quelqu'un pouvait m'aider, ça serait génial.
Merci d'avance !
Marsh Posté le 16-08-2007 à 10:41:21
tu ne dois surtout pas arreter l'écoute...
tu es ici en mode connecté. Une fois que la connexion est établie entre le client et le serveur, tu ne dois pas couper la connexion sauf quand tu arretes ton serveur ou que le client se déconnecte par lui même...
Pour cela, tu dois travailler avec des threads et boucler sur les messages du client tout simplement.
Si tu ne fais pas ça, tu n'y arrivera jamais
Marsh Posté le 16-08-2007 à 10:56:49
moi23372 a écrit : tu ne dois surtout pas arreter l'écoute... |
Donc ne pas utiliser les méthodes BeginAccept et EndAccept, mais plutot lancer manuellement des threads et boucler sur l'écoute ?
Marsh Posté le 16-08-2007 à 11:32:20
'Tain je galère...
Bon, j'ai fait ça :
Code :
|
Le problème, c'est que lorsqu'il fait
Me.tcpClient = Me.tcpListener.AcceptTcpClient()
Il arrête temporairement de recevoir....
J'ai développé un client qui envoie des messages successifs (dans un while, donc plutôt rapidement, ce client étant un client de test, dans la réalité, les messages sont quasiment aussi rapides, puis le serveur fera des accès à une BDD, donc bon...).
Ce client envoie son premier message, reçoit la réponse, envoie de le deuxième, et là, plus rien, ou erreur disant que la connexion n'existe plus.
J'ai pensé à du multithread, c'est à dire créer par exemple 5 ou 6 threads d'écoute, de manière à ce qu'il y en ai au moins un en écoute, mais je ne sais pas si 2 threads peuvent écouter le même port....
La je commence à être perdu...
Marsh Posté le 16-08-2007 à 11:56:44
J'ai lu en diagonale
je ne vois pas ce qui cloche dans ton code >.<
mais "de mémoire", une solution serait:
Tu fais un Accept en boucle et tu dispatches vers d'autres
thread pour le traitement (et la fermeture du socketClient ?).
edit:
http://www.csharpfr.com/infomsg_SO [...] 50683.aspx
Il faudrait utiliser un Pool également ^^ bonne chance
Marsh Posté le 16-08-2007 à 14:28:08
Ouais, ben c'est pas si facile....
Jusqu'à présent j'utilisais la classe TcpClient (une surcouche de la classe Socket).
Pour utiliser ce fameux Poll, faut passer par la classe Socket (comme dans le lien c# que tu m'as laissé).
Mais c'est plus chaud du coup, parce que dans leur exemple, ils expliquent pas ou placer les initialisations, les accepts, la boucle, etc...
Quelqu'un a plus d'infos ?
(je continue à chercher une solution qui fonctionne avec ce poll, je posterais du code tout à l'heure)
Marsh Posté le 16-08-2007 à 14:58:24
Bon...
La communication fonctionne... mais j'ai toujours le même problème. Je poste ce que j'ai fait.
La méthode RunServer() est lancée par le clic sur un bouton du même nom.
Code :
|
La méthode Accept est lancée en boucle par le thread juste au dessus :
Code :
|
DisplayMessage c'est juste un affichage texte dans une rich text box, le tout en asynchrone et GetReponse c'est la fonction qui analyse ce qu'a envoyé le client et qui met en forme la réponse.
Le fonctionnement de mon soft est le suivant :
Je démarre le serveur
Je démarre le client
J'envoie un message depuis le client
Le serveur réceptionne le message et répond
Le client reçoit la réponse et automatiquement envoie un nouveau message...
Et là, plus rien. Le second message n'est pas entendu par le serveur (j'ai donc toujours le même problème)...
Je n'en peux plus... Je vous en supplie... Sortez moi de ce tunnel sombre
Marsh Posté le 16-08-2007 à 15:10:36
regarde le source de ce chat, ça pourrait peut etre t'aider
http://stephaneey.developpez.com/t [...] t/sockets/
Marsh Posté le 16-08-2007 à 16:25:48
Merci Harko.
Ca marche toujours pas comme je veux. Voici mon code :
Code :
|
Le problème est maintenant le suivant :
Le serveur boucle de façon infinie sur l'accept. Dès qu'il a des données, il les récupère dans un autre thread.
Mon client envoie en fait 5 messages d'affilée (via un FOR).
Le premier message est reçu par le serveur, mais les 4 autres sont balancés dans vide. Le fait est que le serveur plante s'il n'y a pas de connexion, donc, il y a une connexion, mais un problème dont je connais pas l'origine....
Une idée ?
Marsh Posté le 09-08-2007 à 12:01:15
Bonjour,
Mon problème va être un peu long a être expliqué, mais j'espère que les plus vaillants pour répondre.
Le schéma est simple.
La ou je travaille, il y a une porte avec un lecteur de badge (lecteur simple à code barre). Ce lecteur est relié à notre réseau en ethernet, et communique avec le serveur sur le protocole TCP, sur le port 2100.
Le serveur possède plusieurs services, qui répondent au lecteur en tant voulu.
Après quelques sniff du réseau, j'ai trouvé les infos envoyées, les échanges etc.
Le but de mon projet est de développer une appli de remplacement pour gérer les badges, la communication, tout ça, étant donné que l'appli actuelle est sous un vieux NT4, et on a très peur d'une panne matérielle, entre autres.
Donc je me suis intéressé à la programmation TCP/IP en vb.net, puisque j'avais ça sous la main et que je m'en sortais pas trop mal.
J'ai commencé par faire une appli serveur qui écoute le port 2100 en asynchrone (pour rien bloquer). Je reçois correctement les informations.
Mais, il faut répondre. Pourquoi ? 2 raisons :
- Le lecteur, lorsque qu'un badge est lu, envoie un paquet TCP qui contient une chaine de 49 caractères, avec dedans le matricule du badge, l'identificaiton du lecteur, la date et l'heure (plus quelques autres chiffres toujours identiques).
- De temps en temps (je n'ai pas trouvé de récurrence pour l'instant), le lecteur envoie un message de la forme *011100000000m et attend une réponse valant :008100012v avec les caractères 0A 0D à la fin (CR et LF).
Après une longue analyse, je commence à mieux comprendre les paquets TCP.
Le lecteur envoie dans son paquet (comme tout paquet tcp je suppose), trois infos importantes : le numéro de séquence, le prochain numéro de séquence et le numéro d'accusé de réception (ACK).
Je pense (et surtout dites moi si je me trompe), que la réponse doit avoir pour séquence le numéro "next sequence" du lecteur. Mais ce n'est pas le cas dans ce que je renvoie...
Un exemple
Lecteur
-------
Sequence : 1234
Next Sequence : 65473
ACK : 25
Serveur
--------
Sequence : 2514
Next Sequence : XXXXX (on s'en fout)
ACK : 1234
Il me semble que c'est pas bon, et que c'est pour ça que la communication ne se fait pas. En fait, on dirait que le lecteur n'entend pas ma réponse.
J'aimerais juste arriver à ce qu'elle capte mon message, que je puisse lui répondre immédiatement, dès que je reçois son message, mais là, je sèche...
Voici mon code (juste pour la réception et émission de message) :
La connexion se fait bien, ça fonctionne puisque j'avais fait des tests avec une appli cliente qui simulait le lecteur, et ça communique correctement.
Dès que je communique avec le lecteur, il ne reçoit pas mes messages...
Voilà, si quelqu'un peut m'aider, ça serait génial...
Merci d'avance