156 lines
5.1 KiB
C#
156 lines
5.1 KiB
C#
//
|
|
// Class: AIS_Telnet
|
|
// Current CLR: 4.0.30319.296
|
|
// System: Microsoft Visual Studio 10.0
|
|
// Author: dani
|
|
// Created: 3/16/2013 12:58:03 PM
|
|
//
|
|
// Copyright (c) 2013 Informatikbüro Daniel Schick. All rights reserved.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Net.Sockets;
|
|
|
|
using log4net;
|
|
|
|
namespace bsmd.AISService.AIS
|
|
{
|
|
public class AIS_Telnet
|
|
{
|
|
|
|
#region private fields
|
|
|
|
private const int BFSIZE = 1024;
|
|
|
|
private NetworkStream tcpStream;
|
|
private TcpClient tcpSocket;
|
|
private string currentString = "";
|
|
private string hostname;
|
|
private int port;
|
|
private DateTime? lastRead;
|
|
|
|
private static ILog _log = LogManager.GetLogger(typeof(AIS_Telnet));
|
|
|
|
#endregion
|
|
|
|
public AIS_Telnet(string theHostname, int thePort)
|
|
{
|
|
this.port = thePort;
|
|
this.hostname = theHostname;
|
|
this.Connect();
|
|
}
|
|
|
|
#region Properties
|
|
|
|
public bool IsConnected
|
|
{
|
|
get { return tcpSocket.Connected; }
|
|
}
|
|
|
|
public string Hostname { get { return this.hostname; } }
|
|
|
|
public int Port { get { return this.port; } }
|
|
|
|
public string StationName { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region public methods
|
|
|
|
private string ReadCurrentUptoNewline()
|
|
{
|
|
int newlineIndex = currentString.IndexOf('\n');
|
|
string result = this.currentString.Substring(0, newlineIndex);
|
|
if (currentString.Length > (newlineIndex + 1))
|
|
currentString = currentString.Substring(newlineIndex + 1);
|
|
else
|
|
currentString = "";
|
|
return result;
|
|
}
|
|
|
|
public string ReadLine()
|
|
{
|
|
|
|
string result = "";
|
|
if (currentString.IndexOf('\n') >= 0)
|
|
return ReadCurrentUptoNewline();
|
|
|
|
|
|
byte[] inputBuffer = new byte[1024];
|
|
|
|
if ((tcpSocket == null) || (!tcpSocket.Connected) || !this.tcpStream.CanRead)
|
|
this.Connect();
|
|
if ((tcpSocket == null) || !tcpSocket.Connected)
|
|
{
|
|
System.Threading.Thread.Sleep(30000); // wait 5 mins if connect is unsuccessful
|
|
return result;
|
|
}
|
|
if (this.tcpStream.DataAvailable)
|
|
{
|
|
try
|
|
{
|
|
int bytesRead = this.tcpStream.Read(inputBuffer, 0, 1024);
|
|
if (bytesRead > 0)
|
|
{
|
|
this.lastRead = DateTime.Now;
|
|
this.currentString += Encoding.ASCII.GetString(inputBuffer, 0, bytesRead);
|
|
if (currentString.IndexOf('\n') >= 0)
|
|
return ReadCurrentUptoNewline();
|
|
if (this.currentString.Length > 1024) this.currentString = ""; // truncate to avoid overflow for wrong client data flow
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.ErrorFormat("exception reading from tcp stream: {0}", ex.Message);
|
|
result = "";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// wenn die Verbindung wegkracht ist immer noch connected true, aber DataAvailable false
|
|
// es gibt anscheinend keinen richtig guten Workaround. Hard case: Nach einer Stunde Inaktivität schließt der Client hier die
|
|
// Verbindung und versucht reconnects. Das bekommt der LS100PortProxy aber nicht immer mit.. Folge sind dann die "stehengebliebenen"
|
|
// Verbindungen
|
|
if (lastRead == null) lastRead = DateTime.Now;
|
|
if ((DateTime.Now - lastRead.Value).TotalSeconds > 600)
|
|
{
|
|
this.tcpSocket.Close();
|
|
this.tcpSocket = null;
|
|
_log.Info("closing inactive TcpClient");
|
|
this.lastRead = DateTime.Now; // reset timer
|
|
}
|
|
|
|
System.Threading.Thread.Sleep(250); // wait a bit
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
if (this.tcpStream != null) this.tcpStream.Close();
|
|
this.tcpSocket.Close();
|
|
this.tcpStream.Dispose();
|
|
}
|
|
|
|
#endregion
|
|
|
|
public void Connect()
|
|
{
|
|
try
|
|
{
|
|
if ((this.tcpSocket != null) && (this.tcpSocket.Connected)) return;
|
|
this.tcpSocket = new TcpClient(this.hostname, this.port);
|
|
this.tcpStream = tcpSocket.GetStream();
|
|
_log.InfoFormat("TCP stream connected ({0}:{1})", this.hostname, this.port);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_log.WarnFormat("AIS_Telnet: cannot connect to ({0}:{1}) : {2}", this.hostname, this.port, ex.Message);
|
|
}
|
|
}
|
|
}
|
|
}
|