TCP read tant qu'on recoit des choses
Bonjour
J'ai besoin de recevoir des données en tcp dont je ne connais pas la taille exacte et pour laquelle je n'ai pas de marqueur de fin genre le "EOF" utilisé dans les exemples du MSDN
J'ai fait cette méthode, copieusement pompée sur des exemples.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| static void ProcessClient(TcpClient client, X509Certificate certificate)
{
// A client has connected. Create the SslStream using the client's network stream.
var sslStream = new SslStream(client.GetStream(), false);
try
{
// Authenticate the server and NOT requires the client to authenticate.
sslStream.AuthenticateAsServer(certificate, false, SslProtocols.Tls, true);
// Authenticate the server and requires the client to authenticate.
//sslStream.AuthenticateAsServer(certificate, true, SslProtocols.Default, true);
// Display the properties and settings for the authenticated stream.
DisplaySecurityLevel(sslStream);
DisplaySecurityServices(sslStream);
DisplayCertificateInformation(sslStream);
DisplayStreamProperties(sslStream);
// Set timeouts for the read and write to 5 seconds.
sslStream.ReadTimeout = 250;
sslStream.WriteTimeout = 5000;
// Read a message from the client.
Console.WriteLine("Waiting for client message...");
byte[] buffer = new byte[20000];
// attente réponse le temps du timeout
int Position = 0; // position dans le buffer = nombre total d'octets recus
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, Position, (buffer.Length - Position));
Console.WriteLine("recu : {0}o", bytes);
Position += (int)bytes;
} while (bytes !=0 );
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Recu texte : {0}", System.Text.Encoding.ASCII.GetString(buffer,0,Position));
Console.Write("Recu bytes :");
for (int i = 0; i < Position; i++)
{
Console.Write("{0}-", buffer[i].ToString());
}
Console.ResetColor();
// Write a message to the client.
byte[] message = Encoding.ASCII.GetBytes("Reponse du serveur de demo !!");
Console.WriteLine("\r\nSending hello message.");
sslStream.Write(message);
}
catch (Exception e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
sslStream.Close();
client.Close();
return;
}
finally
{
// The client stream will be closed with the sslStream
// because we specified this behavior when creating
// the sslStream.
sslStream.Close();
client.Close();
}
} |
Le morceau concerné ici est
Code:
1 2 3 4 5 6 7 8
| int Position = 0; // position dans le buffer = nombre total d'octets reçus
int bytes = -1;
do
{
bytes = sslStream.Read(buffer, Position, (buffer.Length - Position));
Console.WriteLine("recu : {0}o", bytes);
Position += (int)bytes;
} while (bytes !=0 ); |
Mon gros soucis est que forcément on sort de là en timout et que donc forcément j'ai une exception qui me fait sauter. Je tourne le truc dans tous les sens je ne vois pas comment faire et pourtant j'imagine bien que d'autres que moi ont eu à recevoir des choses en TCP sans en connaitre la taille et sans avoir d'identifiant de fin de message !
-J'ai imaginé désactiver le timout et le refaire moi même avec un Stopwatch sw = new Stopwatch(); mais je ne peux pas interrompre le read avec un tel timout perso, seul le timout du read le peut
-J'ai imaginé vérifier dans l'exception si on a déjà reçu des choses mais d'une part je ne trouve pas le nom de l'exception timout (IOexception c'est vague) et d'autre part il est déjà trop tard une fois que l'exception a sautée
Peut on désactiver une exception spécifique une fois un premier read terminé avec réception d'un nombre de byte >0 ?
Quelle autre solution ?
Merci