Tcp Server

  • Hallo zusammen,

    Ich versuche mich schon seit einiger Zeit daran, einen Tcp Server zu bauen, der alle Tcp Ereignisse zur gleichen Zeit steuern kann, da das mit Autoit nicht grade sehr leicht ist, hab ich etwas Zeit dafür gebraucht erstmal auf eine schöne und stabile Idee zu kommen, das Stichwort lautet: "Timer". Habe vorher nur selten mit Timern gearbeitet, meistens waren meine Tcp Programme immer so gebaut, das alles in einer streng geordneten Reihenfolge ablief und der Script immer in die unterschiedlichen Funktionen springen musste, wodurch dann andere Teile des Skripts pausiert werden mussten. Allerdings habe ich jetzt den Dreh raus, denke ich... Den Server den ich nun gecodet habe, kann nun Nachrichten empfangen, senden und Statusabfragen, fast zeitgleich erledigen, was für mich anfangs unmöglich erschien, aber die kleinen netten Timer haben das ganze nun geregelt. Natürlich freue ich mich über Hilfe und Feed Back, aber jetzt zum Script:

    Der Tcp Server:

    [autoit]


    #NoTrayIcon
    #AutoIt3Wrapper_Change2CUI=y

    [/autoit][autoit][/autoit][autoit]

    Opt("MustDeclareVars", 1)
    TCPStartup()

    [/autoit][autoit][/autoit][autoit]

    Global Const $iDelay = 2
    Global Const $iMax = 65
    Global Const $tcpIp = ""
    Global Const $tcpPort = 8000
    Global $iCounter = 0
    Global $tcpListener = TCPListen($tcpIp, $tcpPort, 1)
    Global $tcpAccept = TimerInit()
    Global $iIndex = 0
    Global $tcpSocket[$iMax]
    Global $chkAlive[$iMax]
    Global $tcpRecv[$iMax]
    Global $chkRecv[$iMax]
    Global $chkAnswer[$iMax]
    Global $tcpMsg[$iMax]
    Global $chkMsg[$iMax]

    [/autoit][autoit][/autoit][autoit]

    For $iIndex = 1 To $iMax - 1 Step 1
    $tcpSocket[$iIndex] = -1
    Next

    [/autoit][autoit][/autoit][autoit]

    ConsoleWrite("[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Listening for connections" & @CRLF)

    [/autoit][autoit][/autoit][autoit]

    While True
    For $iIndex = 1 To $iMax - 1 Step 1
    If TimerDiff($tcpAccept) >= 32 Then
    If $tcpSocket[$iIndex] = -1 Then
    $tcpSocket[$iIndex] = TCPAccept($tcpListener)
    If $tcpSocket[$iIndex] <> -1 Then
    ConsoleWrite("[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Socket[" & $iIndex & "] is connected" & @CRLF)
    $chkAlive[$iIndex] = TimerInit()
    $chkRecv[$iIndex] = TimerInit()
    $chkAnswer[$iIndex] = TimerInit()
    $chkMsg[$iIndex] = TimerInit()
    EndIf
    EndIf
    EndIf
    If $tcpSocket[$iIndex] <> -1 Then
    If TimerDiff($chkMsg[$iIndex]) >= 3072 Then
    If $tcpMsg[$iIndex] <> "" Then
    ConsoleWrite("[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Sent " & $tcpMsg[$iIndex] & " to Socket[" & $iIndex & "]" & @CRLF)
    TCPSend($tcpSocket[$iIndex], $tcpMsg[$iIndex])
    $chkAnswer[$iIndex] = TimerInit()
    $chkMsg[$iIndex] = TimerInit()
    EndIf
    EndIf
    If TimerDiff($chkAlive[$iIndex]) >= 4096 Then
    ConsoleWrite("[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Socket[" & $iIndex & "] is disconnected" & @CRLF)
    TCPCloseSocket($tcpSocket[$iIndex])
    $tcpSocket[$iIndex] = -1
    EndIf
    If TimerDiff($chkRecv[$iIndex]) >= 1024 Then
    $tcpRecv[$iIndex] = TCPRecv($tcpSocket[$iIndex], 64)
    If $tcpRecv[$iIndex] <> "" Then
    ConsoleWrite("[" & @HOUR & ":" & @MIN & ":" & @SEC & "] Received: " & BinaryToString($tcpRecv[$iIndex]) & " from Socket[" & $iIndex & "]" & @CRLF)
    For $iCounter = 1 To $iMax - 1 Step 1
    $tcpMsg[$iCounter] = $tcpRecv[$iIndex]
    Next
    $chkAlive[$iIndex] = TimerInit()
    EndIf
    $chkRecv[$iIndex] = TimerInit()
    EndIf
    If TimerDiff($chkAnswer[$iIndex]) >= 2048 Then
    TCPSend($tcpSocket[$iIndex], StringToBinary("Alive"))
    $chkAnswer[$iIndex] = TimerInit()
    EndIf
    EndIf
    Next
    Sleep($iDelay)
    WEnd

    [/autoit]

    Folgenden Client habe ich zum testen genutzt (Prototype ohne Gui):

    [autoit]


    Opt("MustDeclareVars",1)
    TCPStartup()

    [/autoit][autoit][/autoit][autoit]

    Global Const $tcpIp = "127.0.0.1"
    Global Const $tcpPort = 8000
    Global Const $iDelay = 2
    Global $tcpSocket = -1
    Global $tcpRecv
    Global $chkRecv
    Global $chkAnswer
    Global $chkAlive

    [/autoit][autoit][/autoit][autoit]

    While True
    $tcpSocket = TCPConnect($tcpIp, $tcpPort)
    If $tcpSocket <> -1 Then
    $chkRecv = TimerInit()
    $chkAnswer = TimerInit()
    $chkAlive = TimerInit()
    While True
    If TimerDiff($chkRecv) >= 1024 Then
    $tcpRecv = TCPRecv($tcpSocket, 64)
    If $tcpRecv <> "" Then
    If BinaryToString($tcpRecv) = "Alive" Then
    Sleep($iDelay)
    EndIf
    $chkAlive = TimerInit()
    EndIf
    $chkRecv = TimerInit()
    EndIf
    If TimerDiff($chkAnswer) >= 2048 Then
    TCPSend($tcpSocket, StringToBinary("Alive"))
    $chkAnswer = TimerInit()
    EndIf
    If TimerDiff($chkAlive) >= 4096 Then
    TCPCloseSocket($tcpSocket)
    $tcpSocket = -1
    ExitLoop
    EndIf
    Sleep($iDelay)
    WEnd
    EndIf
    Sleep($iDelay)
    WEnd

    [/autoit]

    So das war es erstmal, ich denke mal der Server und der Client, sind so gecodet, das sie leicht in jedes andere Programm eingebunden werden können, da ich keinerlei Funktionen oder Ähnliches mit hineingebaut habe, es ist lediglich die Verbindung der Sockets und der Nachrichtenempfang und Versand, neben ein paar Consolen-Einträgen, in diesem Script vorhanden. Viel spass damit!

    MfG
    Darknoop

    2 Mal editiert, zuletzt von Darknoop (8. April 2009 um 15:24)