Hallo!
Nachdem ich das Forum studiert aber leider nichts zu dem Thema gefunden habe frage ich mal die Spezialisten:
Wo will ich hin: Ein Serverprogramm das via TCP Daten empfängt und in ein Logfile speichert - gibt bereits und funktioniert
Weiter gibt es einen Testclient der Daten schickt - funkt local als auch übers Netz!
Jetzt kommt die Frage:
Ich mache am Server ein Socket auf das lauscht auch ganz brav am Netz und wenn Daten kommen reagiert es wie gewollt darauf. ABER die Verbindung wird nicht nach gleich abgebaut (mit einem TCP-Monitor sieht man das). Kommt die nächste Verbindung wird ein Socket aufgemacht usw usw.
Da jetzt die Clients mehr oder weniger gleichzeitig die Daten schicken werden so hunterte Ports am Server belegt und im schlimmsten Fall kracht es dann!
Ich habe versucht mit der Option TCPTimeout die Zeit zu verkürzen damit das Port schneller freigegeben wird, aber das scheint hier wirkungslos zu sein!
Nur um einen Eindruck zu bekommen ein Screenshot (die Verbindungen sind auch Minuten nachdem der Client beendet worden ist noch da):
Ist das einfach so (weil Windows so ist) oder gibt es da noch einen anderen Trick? Oder wäre hier UDP besser geeignet?
Sicherheitshalber meine beiden Scripts:
Server:
;Druckerdaten erfassung - Server
#include <advfha_proc.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
local $logfile = "d:\printer.log"
local $datei = FileOpen ($logfile, 1)
;TCP-Service starten
TCPStartup ()
local $ip=@ipaddress1
local $port = 2000
local $text=""
local $senderip
local $socket = TCPListen ($ip,$port, 2048)
local $socketid = 0
While 1
$socketid = TCPAccept($socket)
If $socketid >= 0 Then
$senderip = SocketToIP ($socketid)
local $input = TCPRecv ($socketid, 4096)
filewrite ($datei, @HOUR & ":" & @MIN & ":" & @SEC & " " & $senderip & " " & $input & @crlf)
EndIf
WEnd
func SocketToIP($SHOCKET)
Local $sockaddr, $aRet
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")
$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $SHOCKET, _
"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
If Not @error And $aRet[0] = 0 Then
$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aRet = $aRet[0]
Else
$aRet = 0
EndIf
$sockaddr = 0
Return $aRet
EndFunc ;==>SocketToIP
Testclient:
; TCP-Sender test
#include <advfha_proc.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiIPAddress.au3>
#include <WindowsConstants.au3>
#include <GuiIPAddress.au3>
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("TCP-Client", 602, 347, 216, 659)
$Edit1 = GUICtrlCreateEdit("", 32, 56, 545, 217, $ES_READONLY)
;GUICtrlSetState(-1, $GUI_DISABLE)
global $Eingabe = GUICtrlCreateInput("Eingabe", 32, 296, 441, 21)
$Senden = GUICtrlCreateButton("Senden", 496, 296, 75, 25)
GUICtrlSetOnEvent(-1, "senden")
$IPAddress1 = _GUICtrlIpAddress_Create($Form1, 32, 16, 130, 21)
_GUICtrlIpAddress_Set($IPAddress1, "x.x.x.x")
$Port = GUICtrlCreateInput("2000", 168, 16, 49, 21)
;GUICtrlSetData($Port, "2000")
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
Opt("GUIOnEventMode", 1)
;TCP-Service starten
TCPStartup()
global $socket_jn = -1
global $socketid = 0
While 1
GUISetOnEvent($GUI_EVENT_CLOSE, "Ende")
WEnd
func Ende()
exit
endfunc ;==>Ende
func senden()
$kanal = GUICtrlRead($Port)
$ip = _GUICtrlIpAddress_Get($IPAddress1)
local $text = GUICtrlRead($Eingabe)
local $alttext = GUICtrlRead($Edit1)
$socketid = TCPConnect($ip, $kanal)
local $ret = TCPSend($socketid, $text)
TCPCloseSocket($socketid)
$text = $alttext & @crlf & ">" & @HOUR & ":" & @MIN & ":" & @SEC & " on " & $ip & ":" & $kanal & " SocketID:" & $socketid & " " & $text
GUICtrlSetData($Edit1, $text)
GUICtrlSetData($Eingabe, "")
endfunc ;==>senden