﻿#include <GUIConstantsEx.au3>
#include <Misc.au3>
Global $sTitle = 'Interprozesskommunikation' ; Programmname (für _Singleton)
Global $sIPAddress = '127.0.0.1' ; Localhost-IP-Adresse
Global $iPort = 55555 ; beliebige Portnummer (sollte im Bereich zwischen 49152 und 65535 liegen)
Global $hGui, $idInput, $idCheckbox, $MainSocket, $ConnectedSocket = -1, $sData, $sRecv, $iPID

TCPStartup()
If _Singleton($sTitle, 1) = 0 Then ; wenn Server bereits gestartet, dann hier als Client weitermachen
    $ConnectedSocket = TCPConnect($sIPAddress, $iPort) ; Verbindung zum Server herstellen
    If @error Then ; wenn nicht erfolgreich, dann Client beenden mit Fehlermeldung
        MsgBox(16, 'FEHLER!', 'TCPConnect fehlgeschlagen! Fehlernr.: ' & @error)
    Else ; TCP-Verbindung war erfolgreich
		$hGui = GUICreate($sTitle & ' - Client', 360, 80)
		$idCheckbox = GUICtrlCreateCheckbox('Checkbox', 10, 10, 120, 20)
		$idInput = GUICtrlCreateInput('', 10, 40, 340, 20)
		GUISetState(@SW_SHOW, $hGui)
        While True
			$sRecv = TCPRecv($ConnectedSocket, 2048) ; Daten abholen
			If $sRecv <> '' Then
				$sRecv = BinaryToString($sRecv, 4) ; Daten umwandeln
				If StringLeft($sRecv, 2) = 'cb' Then ; wenn Kommando "cb" empfangen, dann die folgende Zahl (1 oder 0) auswerten
					GUICtrlSetState($idCheckbox, StringMid($sRecv, 3, 1) = '1' ? $GUI_CHECKED : $GUI_UNCHECKED)
				EndIf
			EndIf
			Switch GUIGetMsg()
				Case $GUI_EVENT_CLOSE
					ExitLoop
				Case $idCheckbox
					$sData = BitAND(GUICtrlRead($idCheckbox), $GUI_CHECKED) ? 'cb1' : 'cb0'
					TCPSend($ConnectedSocket, StringToBinary($sData, 4)) ; Daten an den Server senden
				Case $idInput
					$sData = GUICtrlRead($idInput)
					TCPSend($ConnectedSocket, StringToBinary($sData, 4)) ; Daten an den Server senden
			EndSwitch
        WEnd
		TCPCloseSocket($ConnectedSocket) ; Verbindung zum Server trennen
    EndIf
Else ; Server läuft noch nicht, also Server starten
	$hGui = GUICreate($sTitle & ' - Server', 360, 480)
	$idCheckbox = GUICtrlCreateCheckbox('Checkbox', 10, 10, 340, 20)
	$idInput = GUICtrlCreateEdit('', 10, 40, 340, 430)
	GUISetState(@SW_SHOW, $hGui)
	$MainSocket = TCPListen($sIPAddress, $iPort)
	If $MainSocket = -1 Then Exit MsgBox(0, $sTitle, 'Server konnte nicht gestartet werden!')
	GUICtrlSetData($idInput, '> Server gestartet!' & @CRLF, 1)
	GUICtrlSetData($idInput, '> Starte Client...' & @CRLF, 1)
	Run(@AutoItExe & ' "' & @ScriptFullPath & '"') ; starte das Script nochmal (als Client)
	If @error Then Exit MsgBox(0, $sTitle, 'Client konnte nicht gestartet werden.')
	GUICtrlSetData($idInput, '> Client gestartet.' & @CRLF, 1)
	While True ; in dieser Schleife wartet der Server auf Daten und es wird GUIGetMsg abgefragt
		If $ConnectedSocket = -1 Then ; wenn noch keine Verbindung hergestellt wurde, dann..
			$ConnectedSocket = TCPAccept($MainSocket) ; abfragen, ob sich der Client verbunden hat
			If $ConnectedSocket <> -1 Then ; wenn Verbindung hergestellt, dann Meldung ausgeben
				GUICtrlSetData($idInput, '> Verbindung hergestellt.' & @CRLF, 1)
				GUICtrlSetData($idInput, '> Warte auf Daten...' & @CRLF, 1)
			EndIf
		Else ; Verbindung ist hergestellt
			$sRecv = TCPRecv($ConnectedSocket, 2048) ; Daten abholen
			If @error Then ; wenn dabei ein Fehler aufgetreten ist, dann ist die Verbindung unterbrochen (Client beendet)
				$ConnectedSocket = -1
				GUICtrlSetData($idInput, '> Verbindung unterbrochen.' & @CRLF, 1)
				GUICtrlSetData($idInput, '> Warte auf Verbindung...' & @CRLF, 1)
			Else ; Daten wurden korrekt empfangen
				$sRecv = BinaryToString($sRecv, 4) ; Daten umwandeln
				If $sRecv <> '' Then
					GUICtrlSetData($idInput, $sRecv & @CRLF, 1) ; und im Editfeld ausgeben
					If StringLeft($sRecv, 2) = 'cb' Then ; wenn Kommando "cb" empfangen, dann die folgende Zahl (1 oder 0) auswerten
						GUICtrlSetState($idCheckbox, StringMid($sRecv, 3, 1) = '1' ? $GUI_CHECKED : $GUI_UNCHECKED)
					EndIf
				EndIf
			EndIf
		EndIf
		Switch GUIGetMsg()
			Case $GUI_EVENT_CLOSE
				ExitLoop
			Case $idCheckbox
				$sData = BitAND(GUICtrlRead($idCheckbox), $GUI_CHECKED) ? 'cb1' : 'cb0'
				TCPSend($ConnectedSocket, StringToBinary($sData, 4)) ; Daten an den Server senden
		EndSwitch
	WEnd
	GUICtrlSetData($idInput, '> Verbindung getrennt.' & @CRLF, 1)
	GUICtrlSetData($idInput, '> Server wird beendet.' & @CRLF, 1)
	TCPCloseSocket($ConnectedSocket)
	Sleep(1000)
EndIf
TCPShutdown()
Exit
