Comment faire pour déterminer si le protocole tcp est connecté ou pas?
J'ai tcpclient objet et je voulez savoir si il est connecté ou pas.
j'ai connecté la propriété de tcpclient mais elle renvoie l'état de la dernière opération. donc ce n'est pas utile.
puis-je utiliser ce code :
bool flag;
flag = (tcp.Client.Poll(10000, SelectMode.SelectWrite));
et
if( tcp.Client.Poll( 0, SelectMode.SelectRead ) )
{
byte[] buff = new byte[1];
if( tcp.Client.Receive( buff, SocketFlags.Peek ) == 0 )
{
flag = false;
}
}
mais il ne fonctionne pas correctement.
Une idée?
c'est mon code côté serveur :
private ArrayList _ClientList = new ArrayList();
public ClsServer(int port)
{
_TCPListener = new TcpListener(IPAddress.Any, port);
_TCPListener.Start();
Thread ListenThread = new Thread(new ThreadStart(ListenForClients));
ListenThread.IsBackground = true;
ListenThread.Start();
}
private void ListenForClients()
{
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this._TCPListener.AcceptTcpClient();
client.ReceiveTimeout = 0;
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.IsBackground = true;
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
try
{
TcpClient tcpClient = (TcpClient)client;
AddObject(tcpclient);
int bytesRead;
string message = "";
byte[] RecievedPack = new byte[1024 * 1000];
NetworkStream clientStream = tcpClient.GetStream();
while (true)
{
bytesRead = 0;
try
{
////blocks until a client sends a message
bytesRead = clientStream.Read(RecievedPack, 0, RecievedPack.Length);
int Len = BitConverter.ToInt32(RecievedPack, 0);
message = UTF8Encoding.UTF8.GetString(RecievedPack, 0, Len);
}
catch (Exception er)
{
//When Client is disconnected
if (er.GetType() == typeof(IOException))
{
RemoveObject(client);
break;
}
}
//message has successfully been received
//do something
}
RemoveObject(client);
}
catch(Exception e)
{
//RemoveObject(client);
}
}
private void AddObject(object obj)
{
int totalcount, index;
totalcount = _ClientList.Count;
index = 0;
while (index < totalcount)
{
TcpClient alcobj = (TcpClient)_ClientList[index];
try
{
if (IPAddress.Equals(((IPEndPoint)alcobj.Client.RemoteEndPoint).Address,
((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address))
{
_ClientList.Remove(alcobj);
break;
}
index++;
}
catch (Exception er)
{
if (er.GetType() == typeof(ObjectDisposedException))
RemoveObject(alcobj);
}
finally
{
totalcount = _ClientList.Count;
}
}
_ClientList.Add(obj);
}
private void RemoveObject(object obj)
{
if (_ClientList.IndexOf(obj) > -1)
{
_ClientList.Remove(obj);
SendClientState(IP, false);
}
}
et c'est le côté client :
public bool IsConnected
{
try
{
if (_TcpClient != null && _TcpClient.Client != null && _TcpClient.Client.Connected)
{
//Detect if client disconnected
if (_TcpClient.Client.Poll(0, SelectMode.SelectRead))
{
byte[] buff = new byte[1];
if (_TcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
{
//Client disconnected
return false;
}
else
{
return true;
}
}
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
private void clsClient()
{
if(!IsConnected())
{
Connecttoserver()
}
}
private void ConnectToServer()
{
try
{
NetworkStream _NetworkStream = _TcpClient.GetStream();
byte[] _RecievedPack = new byte[1024 * 1000];
string _Message = string.Empty;
int _BytesRead;
int _Length;
while (true)
{
_BytesRead = _NetworkStream.Read(_RecievedPack, 0, _RecievedPack.Length);
_Length = BitConverter.ToInt32(_RecievedPack, 0);
_Message = UTF8Encoding.UTF8.GetString(_RecievedPack, 4, _Length);
if (_BytesRead != 0)
{
if (OnReceive != null)
//do something
_NetworkStream.Flush();
}
}
}
catch (Exception exp)
{
//do something
}
}
à côté client, IsConnected() retourne toujours faux et essayer de connecttoserver, de sorte que le serveur auditeur toujours essayer d'ajouter le client dans une liste
Êtes-vous d'allumer
Veuillez lire le FAQ. Stackoverflow n'est pas un forum.
Comment est-ce un forum comme question? Dans tous les cas, la FAQ ne mentionne pas les forums.
SocketOptionName.KeepAlive
? Je pense que vous devez l'activer pour votre code. De toute façon, vous n'avez pas besoin de le faire. La solution générale est de considérer socket connecté, et si le socket opération échoue, gérer harmonieusement la perte de connexion. Mais si vous avez besoin de...Veuillez lire le FAQ. Stackoverflow n'est pas un forum.
Comment est-ce un forum comme question? Dans tous les cas, la FAQ ne mentionne pas les forums.
OriginalL'auteur maryam mohammadi | 2011-08-09
Vous devez vous connecter pour publier un commentaire.
Utiliser ce code au lieu de cela, je l'ai testé et l'aide dans le logiciel de production:
Edit: Toutefois, vous ne peut pas compter sur la vérification de la connexion et si vrai procéder, parce qu'il retourner à l'état de connexion au moment de cette propriété exécuté, par exemple une fois que vous vérifiez
IsConnected
et elle retourne true, et pendant que vous êtes dans le milieu de la communication, la connexion est peut-être perdu là! nous viens de l'utiliser en premier lieu à réduire la probabilité de défaillance, de Sorte que vous avez à envelopper l'ensemble de la communication dans un try/catch et attendre que la connexion est perdue à tout moment!Mise à jour de la réponse, cochez la case modifier.
le client se connecte au serveur une fois et une minuterie d'appel IsConnected, si elle retourne false client tente de se connecter à nouveau. le problème est que la fonction retourne toujours faux pour certains clients!!
peut-être le problème en quelque part d'autre, Comment faites-vous la vérification de chacun des clients? Je pense qu'une méthode est d'utiliser une méthode
public bool IsConnected(TcpClient _tcpClient)
et ajouter une liste de clients à chaque fois qu'un nouveau client est ajouté, à la minuterie, vérifiezforeach (TcpClient client in _clientsArray)
.. c'Est que ce que vous faites? ou chaque client a son propre chronomètre?vous êtes les bienvenus 🙂
OriginalL'auteur Jalal Said
Je suggère de ne pas relayer sur de telles méthodes.
À mon avis, le meilleur moyen est de mettre en place une sorte de keep-alive mécanisme.
Toutes les X secondes, envoyer un petit message et d'attendre une réponse.
Vous êtes probablement déconnecté lorsque:
1. Vous intercepter une exception lorsque vous tentez d'envoyer un message persistant (si vous êtes du côté client).
2. Vous ne recevez pas un message persistant/réponse pour une certaine période de temps.
Je suggère également de ne pas compter sur le haut-TCP keep-alive, je l'ai trouvé pas très fiable.
Mise à jour: Trouvé un joli post pour cette question: Post
OriginalL'auteur Lior Ohana
La seule façon de savoir si oui ou non l'autre extrémité d'une connexion de socket est toujours connecté est d'attraper le résultat d'une opération de lecture ou écriture ou peut-être attraper une exception.
Pour plus d'informations, veuillez vous référer à cette StackOverflow question:
Instantanément détecter client déconnexion du serveur de socket
Voici un petit extrait de code qui est tout simplement à l'aide d'un
Socket
en mode sans blocage et connecté à un serveur.Le "keep-alive" méthode Lior Ohana proposé est aussi une bonne idée. La Force de chaque client afin de "check in" toutes les X secondes. Le client peut détecter le serveur est allé si une exception se produit sur l'écriture, et le serveur sait que le client a disparu si un "keep-alive" le message n'a pas été reçu dans les X secondes.
OriginalL'auteur Chimera
Je suis d'accord avec Lior Ohana parce que j'ai eu ce problème avec des périphériques distants qui ont été utilisés GPRS connexion Tcp. lorsque l'appareil est éteint ou déconnecté, il n'a pas d'alerte à la rompre. Y j'ai utilisé ce code: - je envoyer de temps Spécifique pour les clients
OriginalL'auteur Akbar Jafari