C # - StreamReader.ReadLine ne fonctionne pas correctement!
-
11-09-2019 - |
Question
Simplement j'ai essayé de mettre en œuvre ce que BufferedStreamReader
fait en Java. J'ai un flux de socket ouvert et que vous voulez juste de le lire d'une manière orientée ligne - ligne par ligne
J'ai le code serveur suivant.
while (continueProcess)
{
try
{
StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8);
string command = reader.ReadLine();
if (command == null)
break;
OnClientExecute(command);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
Et le client code suivant:
TcpClient tcpClient = new TcpClient();
try
{
tcpClient.Connect("localhost", serverPort);
StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
writer.AutoFlush = true;
writer.WriteLine("login>user,pass");
writer.WriteLine("print>param1,param2,param3");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
finally
{
tcpClient.Close();
}
Le serveur ne lit que la première ligne (de login>user,pass
) puis ReadLine
retourne null!
Quelle est la meilleure façon d'atteindre ce lecteur orienté ligne comme dans la BufferedStreamReader
Java? : S
La solution
Une ligne typique est-lecteur quelque chose comme:
using(StreamReader reader = new StreamReader(Socket.GetStream(), Encoding.UTF8)) {
string line;
while((line = reader.ReadLine()) != null) {
// do something with line
}
}
(notez le using
pour nous assurer Dispose()
même si nous obtenons une erreur, et la boucle)
Si vous voulez, vous pourriez abstraite cette (séparation des préoccupations) avec un bloc itérateur:
static IEnumerable<string> ReadLines(Stream source, Encoding encoding) {
using(StreamReader reader = new StreamReader(source, encoding)) {
string line;
while((line = reader.ReadLine()) != null) {
yield return line;
}
}
}
(noter que nous avons déplacé cela en fonction et a retiré le « faire quelque chose », en le remplaçant par « retour de rendement », ce qui crée un iterator (une, machine d'état non-tampon paresseusement itéré)
Nous pourrions alors consommer ce aussi simple que:
foreach(string line in ReadLines(Socket.GetStream(), Encoding.UTF8)) {
// do something with line
}
Maintenant, notre code de traitement n'a pas besoin de vous soucier de comment pour lire les lignes -. Simplement donnée une séquence de lignes, faire quelque chose avec eux
Notez que le using
(Dispose()
) applique à TcpClient
aussi; vous devez prendre l'habitude de vérifier les IDisposable
; par exemple (y compris encore votre diagraphie d'erreur):
using(TcpClient tcpClient = new TcpClient()) {
try {
tcpClient.Connect("localhost", serverPort);
StreamWriter writer = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
writer.AutoFlush = true;
writer.WriteLine("login>user,pass");
writer.WriteLine("print>param1,param2,param3");
} catch (Exception ex) {
Console.Error.WriteLine(ex.ToString());
}
}
Autres conseils
Le tout dans votre code de serveur est configuré pour lire une seule ligne par connexion. Vous aurez besoin d'un autre tout dans le essayer de lire toutes les lignes envoyées. Je pense qu'une fois ce flux est configuré sur le côté client, il va envoyer toutes les données. Ensuite, sur le côté serveur, votre flux est effectivement lu une seule ligne de ce courant particulier.
essayé et a obtenu
Le type ou le nom namespace Stream 'n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) Le type ou le nom namespace « StreamReader » n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) Le type ou le nom namespace « StreamReader » n'a pas pu être trouvée (vous manque une directive à l'aide ou une référence d'assemblage?) « System.Net.Sockets.Socket » ne contient pas de définition pour « GetStream »
public string READS()
{
byte[] buf = new byte[CLI.Available];//set buffer
CLI.Receive(buf);//read bytes from stream
string line = UTF8Encoding.UTF8.GetString(buf);//get string from bytes
return line;//return string from bytes
}
public void WRITES(string text)
{
byte[] buf = UTF8Encoding.UTF8.GetBytes(text);//get bytes of text
CLI.Send(buf);//send bytes
}
CLI est une douille. pour certains rezonage la classe TcpClient ne fonctionne pas correctement sur mon pc plus, mais la classe Socket fonctionne très bien.
UTF-8 est le codage StreamReader / enregistreur brin