TcpClient la communication avec le serveur à garder vivante la connexion en c#?
J'ai cette TcpClient code qui fonctionne très bien. Il se connecte à perl server sur un système linux et reçoit tout ce qui serveur cents pour elle. Fonctionne très bien.
public static void Main() {
foreach (ProtocolConnection tcpConnection in TcpConnectionsList) {
ProtocolConnection connection = tcpConnection;
ThreadPool.QueueUserWorkItem(_ => {
ThreadTcpClient(connection);
ManualResetEventTcp.Set();
});
}
... Some code...
}
public static void TcpConnect(ProtocolConnection varConnection) {
int retryCountSeconds = varConnection.RetryEverySeconds*Program.MilisecondsMultiplier;
int count = 0;
while (true) {
try {
using (var client = new TcpClient(varConnection.IpAddress.ToString(), varConnection.Port) { NoDelay = true })
using (var stream = client.GetStream()) {
var data = new Byte[256];
while (!Program.PrepareExit) {
Int32 bytes = stream.Read(data, 0, data.Length);
string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
if (varReadData != "" && varReadData != "PONG") {
VerificationQueue.EnqueueData(varReadData);
Logging.AddToLog("[TCP][" + varConnection.Name + "][DATA ARRIVED]" + varReadData);
} else {
Logging.AddToLog("[TCP]" + varReadData);
}
}
}
} catch (Exception e) {
if (e.ToString().Contains("No connection could be made because the target machine actively refused it")) {
Logging.AddToLog("[TCP][ERROR] Can't connect to server (" + varConnection.Name + ") " + varConnection.IpAddress + ":" + varConnection.Port );
} else {
Logging.AddToLog(e.ToString());
}
}
DateTime startTimeFunction = DateTime.Now;
do {
Thread.Sleep(1000);
} while (((DateTime.Now - startTimeFunction).TotalSeconds < retryCountSeconds));
}
}
Cependant, dans certaines conditions, je vais avoir quelques problèmes avec elle:
- Mon travail de connexion souvent gouttes de connexion après un certain temps d'inactivité j'ai donc mis en œuvre dans le serveur de sorte que lorsqu'il reçoit une requête PING répond avec PONG. Je peux envoyer la commande PING avec l'UDP du serveur et il répondra avec PONG sur tcp, mais je préfère moyen intégré dans le protocole tcp client de sorte qu'il ne envoyer un PING toutes les 60 secondes. Même si UDP solution serait acceptable, je n'ai pas de délai d'attente sur
string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
donc quand PONG n'arrive pas, mon client n'a même pas d'avis de toute façon. Il continue juste à attendre ... ce qui m'amène à.. - Mon autre problème est que, à un certain point
string varReadData = Encoding.ASCII.GetString(data, 0, bytes).Trim();
c'est d'attendre que les données de tous les temps. Lorsque le serveur se bloque ou se déconnecte de mon client, je ne remarque même pas que. Je voudrais serveur pour avoir une sorte detimeout
ou vérifier si la connexion est active. Si elle n'est pas actif, il devrait essayer de se reconnecter.
Ce serait plus simple pour résoudre ce TcpClient ? Comment puis-je mettre en œuvre à la fois moyen de communication s'assurer que si le serveur tombe mes connexions ou mon net est déconnecté le client va le remarquer et rétablir la connexion ?
OriginalL'auteur MadBoy | 2010-06-25
Vous devez vous connecter pour publier un commentaire.
Ce n'est pas
Encoding.ASCII.GetString(data, 0, bytes).Trim();
qui bloque jamais, c'est lestream.Read()
Si vous êtes en train de lire, vous ne pouvez pas facilement faire la distinction entre le serveur(ou de toute passerelle NAT inbetween) l'abandon de votre connexion , et le cas où le serveur n'a tout simplement pas de quoi vous envoyer. Au moins dans le cas où le protocole TCP FIN/paquets RST n'est pas atteindre votre client en cas de panne, ou une passerelle NAT silencieusement à l'abandon de votre connexion.
Ce que vous pouvez faire;
Le dernier point de vous dire si la connexion tcp échoue, il ne vous dira pas si le serveur a un peu échoué, par exemple, si vous appuyez sur CTRL+Z votre perl serveur, il va tout simplement s'asseoir là, de ne rien faire tant que la fenêtre tcp ferme , de sorte que vous pourriez avoir besoin pour mettre en œuvre votre propre heatbeat messges à couvrir un tel cas aussi, si vous en avez besoin.
Le seul problème avec
ReceiveTimeout
est qu'il jette exception et les gouttes de connexion si je dois continuer à faire de nouveaux afin de être en mesure d'envoyer des battements de cœur.OriginalL'auteur nos
Vous devriez vous débarrasser de l'UDP rythme cardiaque tenter et mettre dans un réel TCP battement de coeur. "Ping le serveur à l'aide du protocole UDP est presque vide de sens.
Votre protocole est également absente de message de cadrage.
Lire ces deux articles liés soigneusement (surtout le message de cadrage). Le protocole que vous utilisez actuellement n'a besoin d'une sérieuse révision.
OriginalL'auteur Stephen Cleary