Bonjour,
je suis coincé sur un problème depuis quelques jours...
le problème est le suivant,
j'utilise un TCPClient pour me connecter à un port particulier
jusque là, la connexion se fait bien, je reçois une belle réponse du serveur
directement (networkstream et tcpclient sont toujours ouverts!) j'écris un autre message (commande), le serveur me réponds toujours.
et à la 3e écriture, il me plante... la propriété "DataAvailable" du networkstream est à false... impossible d'avoir une réponse du serveur !
je ne comprends pas...
quelqu'un peut m'aider?
Merci d'avance
Public Function Connect() As Boolean Dim bytes As Int32 Dim responseData As String Try Me._client = New TcpClient(Me._server, Me._port) ' Get a client stream for reading and writing. Me._client.NoDelay = True Me._stream = Me._client.GetStream() Me._buffer = New Byte(Me._client.ReceiveBufferSize) {} bytes = Me._stream.Read(Me._buffer, 0, Me._buffer.Length) responseData = System.Text.Encoding.ASCII.GetString(Me._buffer, 0, bytes) If responseData.Trim.ToLower.Contains("playbox") Then Return True Else Return False End If Catch ex As Exception Return False End Try Return True End Function Public Sub Disconnect() If Me._client IsNot Nothing Then Me._client.Close() End If If Me._stream IsNot Nothing Then Me._stream.Close() End If End Sub Private Function SendCommand(ByVal Message As String) As String 'Dim data As Byte() 'data = System.Text.Encoding.ASCII.GetBytes(Message) 'Me._stream.BeginWrite(data, 0, data.Length, AddressOf DataSent, Nothing) ' String to store the response ASCII representation. Dim responseData As String Dim bytes As Int32 If Me._client.Connected AndAlso Me._stream.CanRead AndAlso Me._stream.CanWrite Then Try ' Translate the passed message into ASCII and store it as a Byte array. Me._buffer = System.Text.Encoding.ASCII.GetBytes(Message) Me._stream = Me._client.GetStream With Me._stream If .CanWrite AndAlso .CanRead Then ' Send the message to the connected TcpServer. .Write(Me._buffer, 0, Me._buffer.Length) '.BeginWrite(Me._buffer, 0, Me._buffer.Length, AddressOf DataSent, Nothing) '.ReadTimeout = 30000 ReDim Me._buffer(Me._client.ReceiveBufferSize) bytes = .Read(Me._buffer, 0, Me._buffer.Length) ' Read the first batch of the TcpServer response bytes. responseData = System.Text.Encoding.ASCII.GetString(Me._buffer, 0, bytes) Return responseData Else Return String.Empty End If End With Catch ex As Exception Return String.Empty End Try Else Return String.Empty End If End Function
Sans doute ne respectes tu pas le protocole de communication du serveur (à propos duquel tu ne donnes aucun renseignements :( )
Je veux dire que peut être tu écris des données alors que tu devrais en lire, ou que tu en lis alors que tu devrais en écrire.
Difficile d'être plus précis sans infos sur le serveur, mais sur le principe c'est sûrement ça :)
Bonjour,
tout d'abord merci pour la réponse
en effet, j'aurais du vous donner plus d'infos sur le serveur
en fait... je ne sais que très peu de chose sur le serveur
=> il est ouvert en communication bi-directionnel sur le port 7001
et en telnet, je fais en commande line :
telnet server port
=> message : hello from server
getstatus
=> message : ok current read : ...
getstatus
=> message : ok current read : ...
donc ce que j'ai reproduis en .NET n'est qu'une communication bi-directionnelle en TCP via le tcpClient.
et cela marche pour :
=> message : hello from server
getstatus
=> message : ok current read : ...
getstatus
=> dataavailable = false!!!
:'(
j'ai retourné tout internet, je ne trouve rien de concret :(
Je maintiens ma suggestion.
J'avoue :oops: ne pas avoir lu ton code. Il est écrit en VB .Net et j'ai horreur de cette syntaxe, lourde, épaisse, inélégante, stupide, indigeste, pas belle, laide, hideuse, enfin bref tu vois ce que je veux dire.
Toutefois, il me semble avoir aperçu du coin de mon oeil porcin que ton tampon de lecture n'est dimensionné qu'une fois selon les données à lire au premier échange.
Si au second échange, et comme tu lis une seule fois en fonction de la taille du tampon, il y a plus de données à lire, elles restent dans le socket. Si à ce moment tu écris alors qu'il y a des données non lues, c'est la panique.
Je ne sais pas si ce que je dit est parfaitement exact, puisque je n'ai pas lu le code. Mais dans l'esprit, c'est ça, tu peux en être sûr.
telnet lui, lit les octets tant qu'il y en a à lire, à chaque coup.
Bonjour,
je suis débutant avec les stream et le tcpClient, je ne comprends pas trop les histoires de buffer/tampon
Pouvez-vous me donner un exemble? meme en C#?
merci d'avance
Le code que tu as donné plus haut, c'est de la génération spontanée ?
Si les tampons sont un problème alors ne les utilises pas ! ;)
Lis les octets un à un tant qu'il y en a à lire
while (le_flux.DataAvailable)
read( un seul octet )
Avec les tampons c'est pareil d'ailleurs sur le principe. Simplement tu dois lire les octets par fournée (une fournée ayant la taille du tampon) TANT QUE il y en a à lire. Et vérifier à chaque lecture le nombre d'octets effectivement lus en testant la valeur retournée par read.
Ton problème est qu'il n'y a pas de boucle while dans ton code. Si j'en crois ce que j'ai aperçu du coin de mon oeil porcin.
Hello,
c'était à cause que le serveur ne répondait qu'après réception d'un carriage return et d'un linefeed...
mais ton idée était très bonne, vu que j'ai appris un peu plus sur les buffer et j'ai ajouté la boucle byte/byte!
un grand merci!!!
Ah oui aussi.
Tous les protocoles en modes textes sont comme ça :)
Quand tu tapes "getstatus" dans telnet puis return, telent ajoute automatiquement \r\n
J'aurais pu te le suggérer. Mais comme tu n'as pas mis le message que tu envoyais dans ton code :twisted: ça aurait été plus de la divination qu'autre chose.