-> Hier kostenlos registrieren
Hallo,
ich habe ein Problem mit dem reconnect zu S7 Steuerungen.
Mein Programm läuft als Windows Service unter W2k8 und greift auf 10 unterschiedliche Steuerungen nacheinander zu.
Das Ganze passiert per Connection Pooling, d.h. ich erzeuge mir eine Liste mit den Verbindungen, verbinde mich mit der S7 (teilweise über IBH) und bei Bedarf wird die Verbindung von einer Funktion verwendet.
Leider passiert es sporadisch dass die Verbindung kurzzeitig verloren geht und danach nicht wieder neu aufgebaut werden kann.
Dies äußert sich wenn das Ergebnis von Connection.readBytes(flags, area.Db, start, bytesToRead, buf) = 1025 ist.
Was kann man da machen?
Hier mal etwas Code.
Der Connection Pool:
Auf- und Abbau der Verbindung:
Und der Lesevorgang:
Der Hauptteil von ReadArea :
Ich wäre für jede Hilfe dankbar.
Gruß
Martin
ich habe ein Problem mit dem reconnect zu S7 Steuerungen.
Mein Programm läuft als Windows Service unter W2k8 und greift auf 10 unterschiedliche Steuerungen nacheinander zu.
Das Ganze passiert per Connection Pooling, d.h. ich erzeuge mir eine Liste mit den Verbindungen, verbinde mich mit der S7 (teilweise über IBH) und bei Bedarf wird die Verbindung von einer Funktion verwendet.
Leider passiert es sporadisch dass die Verbindung kurzzeitig verloren geht und danach nicht wieder neu aufgebaut werden kann.
Dies äußert sich wenn das Ergebnis von Connection.readBytes(flags, area.Db, start, bytesToRead, buf) = 1025 ist.
Was kann man da machen?
Hier mal etwas Code.
Der Connection Pool:
Code:
public S7Connection GetConnectionByServer(string server, int port, bool ibh)
{
foreach (var ls in this)
if (ls.Name.Equals(server))
return ls;
var lib = new S7Connection();
//libnodave.daveSetDebug(libnodave.daveDeb);
var serialType = new libnodave.daveOSserialType
{
rfd = libnodave.openSocket(port, server)
};
serialType.wfd = serialType.rfd;
lib.IsIBH = ibh;
if (ibh)
{
lib.Interface = new libnodave.daveInterface(serialType, server, 0, libnodave.daveProtoMPI_IBH,
libnodave.daveSpeed187k);
lib.Interface.setTimeout(1000000);
lib.Connection = new libnodave.daveConnection(lib.Interface, 2, 0, 0);
}
else
{
lib.Interface = new libnodave.daveInterface(serialType, server, 0, libnodave.daveProtoISOTCP,
libnodave.daveSpeed500k);
lib.Interface.setTimeout(1000000);
lib.Connection = new libnodave.daveConnection(lib.Interface, 0, 0, 2);
}
// libnodave.daveSpeed1500k);
// lib.Interface.initAdapter();
lib.ConnectResult = lib.Connection.connectPLC();
lib.Connected = lib.ConnectResult == 0;
lib.Name = server;
lib.IP = server;
lib.Port = port;
Add(lib);
return lib;
}
Auf- und Abbau der Verbindung:
Code:
public bool Connect()
{
ConnectResult = Connection.connectPLC();
Interface.initAdapter();
if (ConnectResult==0)
Connected = true;
return true;
}
public void Disconnect()
{
Connection.disconnectPLC();
Interface.disconnectAdapter();
Connected = false;
}
Und der Lesevorgang:
Code:
public List<string> ReadAll()
{
try
{
lock (_lockObject)
{
if (_connectionIsReading) // zum Absichern dass nicht doppelt gelsen wird
return null;
_connectionIsReading = true;
}
int i = 0;
if (!Connected)
{
i = Connection.connectPLC();
Connected = true;
if (i != 0)
LogIt(String.Format("Conection result on reconnect : {0}", i));
Interface.initAdapter();
}
var returnlist = new List<string>();
// Lesen und Zuordnen der Werte
foreach (var area in _dataAreaList)
{
var readarea = ReadArea(area); // area ist eine Klasse welche Speicherbereiche liest und die meinen Eigenschaften zuordnet
if (readarea != null)
returnlist.AddRange(readarea);
else
{ // Wenn das Ergebnis null ist ist etwas schief gelaufen und die Verbindung muss neu aufgebaut werden. Daher Abbruch des Lesens und Disconnect.
Disconnect();
break;
}
System.Threading.Thread.Sleep(100);
}
if (!IsIBH)
{
i = Connection.disconnectPLC();
if (i != 0) // War bisher immer 0
LogIt(String.Format("*****ALERT !!! disconnectPLC result = {0} !!!!******", i));
}
return returnlist;
}
catch
{
return null;
}
finally
{
_connectionIsReading = false;
}
}
Der Hauptteil von ReadArea :
Code:
var remainBytes = area.Size;
// var start = 0;
var start = area.StartAddress;
do
{
// Wenn Size > 220 dann in 220er Blöcke teilen und jeweils zuordnen
var bytesToRead = remainBytes > 220 ? 220 : remainBytes;
remainBytes = remainBytes - bytesToRead;
var buf = new byte[bytesToRead];
int i = 0;
lock (_lockObject)
{
i = Connection.readBytes(flags, area.Db, start, bytesToRead, buf);
}
if (i != 0) // Alle paar Tage kommt hier als Ergebnis 1025 und danach geht nichts mehr
{
LogIt(String.Format("*****ALERT {6} !!! readBytes DB{1}.{2} Size:{3} Start:{4} Length:{5} result = {0} Skip Area !!!!******", i,
area.Db, area.StartAddress, area.Size, start, bytesToRead,CPName ));
return null;
}
Array.Copy(buf, 0, area.Buffer, start-area.StartAddress, bytesToRead);
start += bytesToRead;
} while (remainBytes > 0);
Ich wäre für jede Hilfe dankbar.
Gruß
Martin