Entwickler-Ecke

Internet / Netzwerk - Problem beim Nutzen von Socket setsockopt und SO_KEEPALIVE


Muck - Di 05.01.10 00:14
Titel: Problem beim Nutzen von Socket setsockopt und SO_KEEPALIVE
Hallo,

ich habe eine Serviceanwendung im Einsatz, die mit einem Hardwarerouter verbunden ist. Der Router sendet debug Informationen zu allen verbundenen Clients. Alles laeuft soweit fehlerlos. Mein Problem:
Wenn der Router abgeschaltet wird bekommen ich ein DISCONNECT EVENT, aber falls der Router via Web Interface Rebootet wird so bleibt die Verbindung bestehen jedoch erhalte ich keine Daten mehr. Der Router vergisst einfach, dass Clients verbunden sind.
Leider gehen in diesem Augenblick Daten verloren, da ist kein Zwischenspeicher oder Protokoll.

Habe daher also versucht SO_KEEPALIVE einzustellen.
Jedoch beide der folgenden Code Strecken liefern als Ergebnis -1 = SOCKET_ERROR:

1. SetSockOpt setzen im CONNECT Ereignis (soll Socket 1.1 kompatibel sein)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
uses WinSock;

procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
var I,J,K:Integer;
begin
Memo1.Lines.Add('connect');
I:=1;
J:=SizeOf(I);
K:=WinSock.setsockopt(Socket.Handle,SOL_SOCKET,SO_KEEPALIVE,PAnsiChar(@I),J);
Memo1.Lines.Add(IntToStr(I)); // Return 0
Memo1.Lines.Add(IntToStr(k)); // Ergebnis -1 Error
end;


2. WSAIOCTL (soll ab Socket 2 laufen, kann sein, dass Delphi 2009 nur 1.1 nutzt ? )

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
const SIO_KEEPALIVE_VALS=$98000004;


function WSAIoctl(s: TSocket; cmd: DWORD; lpInBuffer: PCHAR; dwInBufferLen:
  DWORD;
  lpOutBuffer: PCHAR; dwOutBufferLen: DWORD;
  lpdwOutBytesReturned: LPDWORD;
  lpOverLapped: POINTER;
  lpOverLappedRoutine: POINTER): Integer; stdcallexternal 'WS2_32.DLL';


procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
type ker = record onoff,keeptime,keepint:Integer;end;
var I,J,K:Integer;ke:ker;
begin
Memo1.Lines.Add('connect');
KE.onoff:=1;
ke.keeptime:=1000;
ke.keepint:=500;
K:=WSAIOCTL(socket.Handle,SIO_KEEPALIVE_VALS,PWideChar(@KE),sizeof(KE),nil,0,@j,nil,nil);
Memo1.Lines.Add(IntToStr(J)); // 4 Bytes Return
Memo1.Lines.Add(IntToStr(k)); // -1 ERROR
end;


Wer weiss was falsch ist oder einen Rat, leider kann ich nicht die Firmware des Router aendern, so dass ein CLOSE Connection abgesetzt wird falls ein Soft Reboot gemacht wird. Oder ist die einzigen Moeglichkeit staendig einen PING abzuseten. Andere haben das geloest indem alle 10 Sekunden ein den Socket geschrieben wird und dann ein Schreibfehler entsteht. In meinem Fall bin ich mir jedoch nicht sicher, ob der Router ueberhaupt eingehende Pakete auswertet und was nach z.B. 1 Woche Betrieb passiert mit der Unmenge von Paketen.

Na ja, vielleicht hat ja jemand ein ganz einfache Loesung :-)

Danke

Markus


Narses - Di 05.01.10 00:34

Moin!

Ich verwende einen funktional identischen Code erfolgreich, um eine andere Socket-Option zu setzen. Würde also den Code für OK halten. Was sagt den das MSDN zu SO_KEEPALIVE konkret? Vielleicht geht das in der Situation nicht? :gruebel:

cu
Narses


Astat - Di 05.01.10 00:48

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
.. Würde also den Code für OK halten. ...


Nöö, Socket.SocketHandle

Es muss das Sockethandle und nicht das Fensterhandle verwendet werden.

lg. Astat


Muck - Di 05.01.10 01:05

Blind, lol,

habe den Delphi Code durch abschreiben von einem C Code generiert. Wohl nicht genug Kaffee gehabt.

Funktion gibt nun Null erfolgreich zurueck. Es ist jetzt 5pm uhr hier, also Feierabend, werde dann morgen mit dem Soft Reset des Router spielen.

Vielen Dank

Markus von weit wech


Narses - Di 05.01.10 01:24

Moin!

user profile iconAstat hat folgendes geschrieben Zum zitierten Posting springen:
Nöö, Socket.SocketHandle
:shock:
user profile iconAstat hat folgendes geschrieben Zum zitierten Posting springen:
Es muss das Sockethandle und nicht das Fensterhandle verwendet werden.
Natürlich... :autsch: Hab´s in meinem Code auch drin :roll:, aber hier ebenfalls überlesen... :nut:

Gut, dass wenigstens noch einer hier wach ist! :beer: :gaehn:

cu
Narses