TcpClient - Une connexion existante a dû être fermée par l'hôte distant
L'Info
J'ai été le développement d'un web serveur http en c# et a décidé d'ajouter une fonctionnalité de console à distance. La console peut être utilisé à partir de n'importe quel endroit et utilise un TcpListener (serveur web) et un TcpClient (console distante) pour envoyer des commandes et de fonctions au travers.
Le Code
C'est ce que mon serveur ressemble:
TcpListener consoleListener = new TcpListener(consolePort);
consoleListener.Start();
byte[] bytes = new Byte[256];
string data = null;
while (true)
{
TcpClient client = consoleListener.AcceptTcpClient();
data = null;
byte[] msg = { 0 };
int i;
while ((i = client.GetStream().Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
if (data == "shutdown")
{
//Server shutdown logic.
}
//Other commands here...
else
{
msg = Encoding.ASCII.GetBytes("Invalid command. Type 'help' or '?' to get a list of commands.");
}
client.GetStream().Write(msg, 0, msg.Length); //sends return message to console
}
client.Close(); //closes connection between client and server after EVERY command. Connection is reopened when a new command is sent.
}
Note - Le serveur est exécuté sur un thread séparé à la fois le serveur et la console principale de l'application thread.
C'est mon client:
public static string Communicate(string text)
{
try
{
TcpClient client = new TcpClient(ip, port); //initializes tcpclient (ip and port are correct)
byte[] data = System.Text.Encoding.ASCII.GetBytes(text); //converts text to bytes for stream writing
NetworkStream stream = client.GetStream();
stream.Write(data, 0, data.Length);
Console.WriteLine("Sent data: " + text);
data = new Byte[256];
string responseData = String.Empty; //initializes responsData string
Int32 bytes = stream.Read(data, 0, data.Length);
responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
client.Close();
return responseData; //returns what server writes
}
catch (Exception ex)
{
return "An error occured\n" + ex.ToString();
}
}
Le Problème
Je peux envoyer une commande au serveur avec un retour réussi. Cependant, lorsque j'essaie d'envoyer une autre commande, le serveur envoyait le message d'erreur ci-dessous:
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at ---.Server.ConsoleListener() in X:\Users\---\Documents\Visual Studio 2013\Projects\---\---\Program.cs:line x
Je sais que ce n'est pas de pare-feu ou de l'administrateur de l'élévation des problèmes que je peux envoyer une commande par le biais de succès. C'est seulement le deuxième commande envoyée qu'elle génère cette erreur.
Voici une capture d'écran décrivant le problème:
EDIT: En faisant une petite recherche, j'ai trouvé que le problème est probablement à la suite d'une petite erreur dans ma boucle for. Cependant, je ne connais pas de moyen de résoudre ce que je ne connais pas exactement le problème :). Merci de m'aider à l'identifier afin que je puisse corriger.
Merci encore
merci pour la note je vais mettre à jour maintenant!
comment suis-je censé mettre en œuvre que - désolé
rodit, vous pouvez envoyer la commande de longueur avant de la commande ou envoyer un char spécial comme
\n
après la commande et vérifier que.merci encore
OriginalL'auteur rodit | 2014-07-15
Vous devez vous connecter pour publier un commentaire.
Il semble que votre client ferme la connexion après un message.
Si vous souhaitez persister la connexion, vous devriez avoir une boucle sur le client similaire à celui que vous avez sur le serveur. Si vous souhaitez établir une nouvelle connexion à chaque fois que vous devez fermer le flux de données gracieusement sur le service et ne pas avoir une boucle de ce genre. Vous aurez toujours besoin de boucle dans le cas où le message est plus ou vous avez besoin de spécifier la longueur maximale de la commande.
un "verte" (à l'acceptation d'une réponse) ne doit pas être une récompense pour quelqu'un qui vous a aidé, s'ils n'ont pas aussi la réponse à la question que vous avez demandé.
noté, merci pour l'astuce 🙂
OriginalL'auteur Stilgar
Je ne sais pas si vous avez résolu votre problème ou pas, mais je suppose que vous devriez poster votre solution de contournement au moins pour que d'autres puissent le consulter.
Je ne pas bien comprendre votre question, mais j'ai eu la même exception, mais la mienne a été déclenchée alors que le client déconnecté et le serveur a été d'essayer de lire le flux de données (networkStream).
J'ai eu une commande unique pour la lecture
Comme faisant l'objet d'une réponse suggérée j'ai changé pour:
ce produit également la question du client disque, donc j'ai eu à faire ce
J'ai dû le faire car il n'a pas d'importance si elle est sur un client ou sur un serveur de l'exception est le même. hôte de déconnexion pendant ce temps mon exception a été CLIENT de déconnexion et de ce message générique erronée de moi à la solution.
Désolé si le code n'est pas collé à partir de vs mais j'ai tapé ici donc, fixer la capitalisation de sorte qu'il peut compiler.
Espère que cela aide quelqu'un.
pourquoi le faire alors qu'à la place de tout? première requête peut échouer, non?
OriginalL'auteur Alex RG
J'ai eu la même solution. c'est généralement ce qui arrive si le client est déconnecté. Solution de Alex RG ne fonctionne pas malheureusement. vous obtiendrez une autre exception. La meilleure des solutions est décrit ici par Microsoft
vous avez besoin de vérifier à l'aide de
CanRead
OriginalL'auteur batmaci