TcpClientConnect.GetStream()

Résolu
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009 - 25 juin 2008 à 15:12
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009 - 30 juin 2008 à 10:46
Bonjour,

je souhaite programmer un serveur TELNET avec TcpListener, TcpClient, NetworkStream,...

Avec ce programme ci-dessous, un client TELNET se connecte à mon programme, le prg reçoit les commandes
clavier du client, mais le programme passe ensuite (Après 2-3 cmdes) en non responding.
Je pense qu'avec l'utilisation de TIMER et GetStream cela ne fait pas bon ménage.

Comment éviter cela ?

----------------------------------------------------------------------------------------------
Imports System.Net.Sockets
Imports System.Net
Imports System.Text

Public Class Form1

    '********Déclaration de mes variables********
    Dim tcpClientConnect As TcpClient
    Dim port As Int32 = 23
    Dim localAddr As IPAddress = IPAddress.Parse("10.50.11.3")
    Dim TcpServer As New TcpListener(localAddr, port)
    Dim stream As NetworkStream

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    '********Activation du Timer TmrRefresh (Utilisé pour accepter la connexion du client)********
        TcpServer = Nothing
        TmrRefresh.Enabled = True
        TmrData.Enabled = False

        On Error GoTo ErroLoad
    '********Démarrage du TcpListener********
        TcpServer = Nothing
        TcpServer = New TcpListener(localAddr, port)
        TcpServer.Start()

        LblSckStatus.Text = "Server started at 10.50.11.3 / " & port

        Exit Sub

ErroLoad:
        MsgBox(Err.Number & " - " & Err.Description)

    End Sub

    Private Sub CmdQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CmdQuit.Click
    '********Arrêt du TcpServer + connexion avec client********
        tcpClientConnect.Close()
        TcpServer.Stop()

        TmrRefresh.Enabled = False
        TmrData.Enabled = False

        End

    End Sub

 
    Private Sub TmrRefresh_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TmrRefresh.Tick
'********Désactivation du Timer TmrRefresh (Utilisé pour accepter la connexion du client une seule fois !!)********
'********Activation du Timer TmrData(Utilisé pour lire les données du NetworkStream)********
        If TcpServer.Pending <> True Then
            tcpClientConnect = TcpServer.AcceptTcpClient
            LblSckStatus.Text = "Client accepted "
            TmrRefresh.Enabled = False
            TmrData.Enabled = True
        End If

    End Sub

    Private Sub TmrData_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TmrData.Tick
'********Lecture du NetworkStream, si donnée dispo...C'est ici que ça bug..********
        Dim i As Integer
        Dim bytes(1024) As [Byte]
        Dim data As [String] = Nothing

        i = 0
        stream = tcpClientConnect.GetStream()

        If tcpClientConnect.Connected AndAlso stream.CanRead AndAlso stream.CanWrite Then

            i = stream.Read(bytes, 0, bytes.Length)

            If i <> 0 Then
                data = Encoding.ASCII.GetString(bytes, 0, i)
                TxtData.Text = TxtData.Text + data & " - " & i

            End If
        End If

    End Sub
End Class

Merci,
Marco

9 réponses

NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
26 juin 2008 à 15:47
Bonjour

Je ne voudrais pas dire de bêtise, mais je crois que :
i = stream.Read(bytes, 0, bytes.Length)

attend que tu ai reçu les 1025 (0 to 1024) octets avant de te rendre la main.

Pourquoi mettre "stream" en attribut alors d'une définition locale suffirait ?

Et accessoirement :
TxtData.Text = TxtData.Text + data & " - " & i
Peut être remplacé par :
TxtData.Text += data & " - " & i

L'ouverture d'esprit ne se limite pas toujours à une fracture du crâne.
VB (6, .NET1&2), C++, C#.Net1
Mo
3
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
26 juin 2008 à 16:57
Bonjour

Mettre l'écoute sur un thread ...

L'ouverture d'esprit ne se limite pas toujours à une fracture du crâne.
VB (6, .NET1&2), C++, C#.Net1
Mo
3
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
27 juin 2008 à 10:55
Bonjour,

Tu inaugures ma nouvelle signature .

A la place de ton Do/Loop sans condition, utilises comme condition de fin la prop Connected de ton TcpClient (note, pour détecter à coup sûr une déconnexion, il faut communiquer de temps en temps, avec un espace suivit d'un retour chariot, par exemple).

Et sitot que ton test détecte une déconnexion, il relance le thread d'écoute des connexions.

nota : Sleep est une méthode partagée, faire "trd1.Sleep(10)" ou "trd2.Sleep(10)" ou encore "Threading.Thread.Sleep(10)" c'est exactement la même chose, ça agit sur le même thread, à savoir le thread appelant..

http://nhen0039.chez-alice.fr/index.php
3
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009
26 juin 2008 à 16:51
Bonjour,

Plus de bug, en utilisant un thread (Explications) :

Imports + Déclarations variables

Imports System.Threading

Private trd As Thread 'New thread
Dim Thrdata As [String] = Nothing 'New thread

Timer Refresh

 trd = New Thread(AddressOf  ThreadData)
 trd.IsBackground = True
 trd.Start()

Thread = ThreadData

 Private Sub ThreadData()
  Dim i As Integer
  Dim bytes(1024) As [Byte]

        Do
           i = 0

            stream = tcpClientConnect.GetStream()
            i = stream.Read(bytes, 0, bytes.Length)

            If i <> 0 Then

                Thrdata = Thrdata & Encoding.ASCII.GetString(bytes, 0, i)
                'Traitement ensuite de la variable globale ThrData

            End If
        Loop

 End Sub

Pour 1025 et stream, c'est parce que je dois pouvoir écrire et lire le stream (NetworkStream) ou pouvoir
faire autre chose avec ma tâche stype écouter un port série...

TxtData.Text += data & " - " & i, c'est plus propre en effet.

!!! J'ai un soucis : tant qu'un client telnet (Putty, MSDos : Telnet IP Adresse) n'est pas connecté,
la tâche est en attente... Cela est dû à ceci (Je pense) "If TcpServer.Pending <> True Then" (Dans un timer),
des idées pour ne pas perturber le fonctionnement de la tâche même si pas encore de client telnet connecté ?

Merci,
Marco
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009
27 juin 2008 à 10:20
Bien vu, je l'ai fait et ça marche nickel, merci.

Load de la Form

  trd1 = New Thread(AddressOf ThreadConn)
  trd1.IsBackground = True
  trd1.Start()
       
 trd2 = New Thread(AddressOf ThreadData)
 trd2.IsBackground = True
 trd2.Start()

Thread d'écoute de la connection

 Private Sub ThreadConn()

        If TcpServer.Pending <> True Then
            tcpClientConnect = TcpServer.AcceptTcpClient
            stream = tcpClientConnect.GetStream()
        End If

  End Sub

Comment puis-je suspendre dans mon code ma connection TcpListener, TcpClient, Threads (Si un client se déconnecte) et reprendre un nouveau ou même client qui se connecte par après ?

Merci,
Marco
0
NHenry Messages postés 15112 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 13 avril 2024 159
27 juin 2008 à 10:28
Bonjour

- Tu veux dire gérer les coupure accidentelle des connexion ?
Là, il faut enregistrer les données en stock et trouver un moyen de repérer à coup sûr (pour éviter certains type de pirates) le client pour restaurer les valeurs.

L'ouverture d'esprit ne se limite pas toujours à une fracture du crâne.
VB (6, .NET1&2), C++, C#.Net1
Mo
0
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009
27 juin 2008 à 10:44
Bonjour,

non c'est pour une coupure "voulue" par l'utilisateur. Et ensuite pour gérer, un reconnexion "voulue". Mais en laissant le TCPListener tjs
prêt à recevoir/écouter une nouvelle connexion.

Mon souci est que (Code du Bouton DISCONNECT CLIENT) :

tcpClientConnect.Close()     'Arrêt de la connexion du client
trd1.Abort()                         'Arrêt du Thread qui gère If TcpServer.Pending <> True then tcpClientConnect = TcpServer.AcceptTcpClienttrd2.Abort()                         'Arrêt du Thread qui gère stream <gras>tcpClientConnect.GetStream() / i stream.Read(bytes, 0, bytes.Length)</gras>
trd1.Sleep(2000)                 'Timer d'arrêt du thread qui gère la coonexion du client au TCPListener (Serveur d'écoute)
trd2.Sleep(2000)                 'Timer d'arrêt du thread qui gère la lecture du Networkstream (Canal entre serveur-client)
trd1.Start()                          'Démarrage du thread de connexion

En me déconnectant (Via un bouton DISCONNECT CLIENT), le thread trd2 tourne encore alors que pas de
client connecté (>> Lecture du NetworkStream qui bug forcèment) ...

Merci,
Marco
0
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009
27 juin 2008 à 16:21
Ok pour Threading.Thread.Sleep(1000)

J'ai solutionné mon souci avec "Try ... Catch" devant tcpClientConnect = TcpServer.AcceptTcpClient ettcpClientConnect.GetStream()

Lors d'un appel d'un thread à partir d'un évenement MSCOMM_EVENT (Je sais qu'il existe d'autre classe
port série, mais bon...), comment ensuite à la fin du thread rendre la main à l'évenement ?

Merci,
Marco
0
Marko007 Messages postés 96 Date d'inscription mardi 15 mai 2007 Statut Membre Dernière intervention 29 janvier 2009
30 juin 2008 à 10:46
Ok,

les évenements type MSCOMM_EVENT, TIMER_EVENT peuvent se déclencher avec l'utilisation des threads.
(Le bug était de mon côté) ;o)

Merci,
Marco
0
Rejoignez-nous