Autoit TCP Server Client Response

12/30/2014 02:56 golle12#1
Guten Abend liebe Elitepvpers Community

und zwar habe ich follgendes Problem, ich programmiere gerade in autoit einen Multi Server für eine begrenzte Anzahl Clients.Das Senden und Empfangen jeweils funktioniert, nur ist es so, dass ich in eine For-Schleife sämtliche Verbindungen in einer Array durch gehe, und somit jeden Client, der ein Socket mit dem Server aufgebaut hat, eine Nachricht bekommt, die eigentlich nur der eine Client, der die Anfrage an den Server gesendet, erhalten sollte. Und da wollte ich fragen wie ich dies bewerkstelligen kann.

PS:Hier ein Beispiel wo in einer For-Schleife an alle Clients das Packet gesendet wird: Nur wie mache ich, dass das es das Socket nimmt, welches die Anfrage geschickt hat?

PHP Code:
For $x 0 To UBound($Verbindung) - 1
TCPSend
($Verbindung[$x],$Login_Ack_Req_Failed)
Next 
mfg golle12
12/30/2014 03:04 alpines#2
Du iterierst das Client-Array nach dem Packet das du abfangen möchtest. Wenn du das erhalten hast merkst du dir einfach welche Iteration das ist (das wäre $x in deinem Fall) und schickst dann das was du willst dorthin.
01/02/2015 00:31 golle12#3
Hm ich habe alles versucht die Verbindung mit dem bestehenden Client zu speichern und die Schleife dann zu verlassen, aber irgendwie stelle ich mich zu blöd an und es klappt nicht so wie es soll entweder wird an niemanden etwas geschickt, an alle oder an ein Socket was gar keine Anfrage gestellt hat. Und zwar Vergleiche ich bei mir die Verbindung mit dem bestehenden Socket und ist dies gleich soll er die Schleife verlassen... naja wie oben beschrieben nicht ganz das was es eigentlich machen soll.

PHP Code:
*$MaxConnect 100
*Global $Verbindung[$MaxConnect]
*
$name TCPNameToIP("dyndnsDienst")
*
$Socket TCPListen($name7294$MaxConnect)

For 
$x 0 To UBound($Verbindung) - 1
If $Verbindung[$x] == $Socket Then
TCPSend
($Verbindung[$x],$Disconnected_Client_Ack)
TCPCloseSocket($Verbindung[$x])
$Verbindung[$x] = -1
ExitLoop
EndIf
Next 
Ich hoffe ihr könnt mir helfen

mfg golle12
01/02/2015 01:01 alpines#4
Du speicherst doch nichts im Verbindungsarray ab, wie willst du das dann mit einem Socket vergleichen?
01/02/2015 16:14 lolkop#5
Hier mal ein kleiner Beispielaufbau für den Server:
Code:
Global $clientArray[1]=[0]
TCPStartup()
$listenSocket = TCPListen(@IPAddress1, 1337)
HandleWSAErrors(0)

While True
	$connectedSocket = TCPAccept($listenSocket)
	HandleWSAErrors(0)
	If $connectedSocket<>-1 Then AddClient($connectedSocket)
	For $i=1 To $clientArray[0] ; loop through all connected clients
		$currentRcv = TCPRecv($clientArray[$i],1024)
		If HandleWSAErrors($i) Then ExitLoop ; handle errors for the current client
		If $currentRcv<>'' Then OnReceiveMessage($clientArray[$i], $currentRcv) ; handle incomming messages in a seperate function
	Next
WEnd

Func OnReceiveMessage($socket, $message)
	ConsoleWrite($socket&' has just send: '&$message&@CRLF) ; print out, whatever the client sends
EndFunc

Func AddClient($socket) ; add the socket to the clientArray
	$clientArray[0]+=1
	ReDim $clientArray[$clientArray[0]+1]
	$clientArray[$clientArray[0]]=$socket
	ConsoleWrite($connectedSocket&' just connected'&@CRLF)
EndFunc

Func DelClient($id) ; close the socket and remove it from the clientArray
	TCPCloseSocket($clientArray[$id])
	ConsoleWrite($clientArray[$id]&' just disconnected'&@CRLF)
	$clientArray[0]-=1
	For $i=$id To $clientArray[0]
		$clientArray[$i]=$clientArray[$i+1]
	Next
	ReDim $clientArray[$clientArray[0]+1]
EndFunc

Func HandleWSAErrors($id, $error = @error)
	Switch $error
		Case -1, 0 ; no error
			Return False
		Case 10054 ; connection reset by peer
			DelClient($id)
		Case Else ; unhandled error
			ConsoleWrite("Error: "&$error&@CRLF)
	EndSwitch
	Return True
EndFunc
In der OnReceiveMessage Funktion würdest du auf jeweils eintreffende Nachrichten reagieren.

Idealerweise würdest du natürlich alle Nachrichten mit speziellem Ende senden und solange die TCP-Queue auslesen, bis das Ende erreicht wurde (quasi ein Buffer pro Client).
Der Einfachheit halber habe ich das hier mal ausgelassen.
01/05/2015 00:16 golle12#6
Hallo nochmal ich habe versucht mein Beispiel auf meins zu übertragen aber es funktionierte nicht ganz so wie es sollte daher habe ich es wieder zurückgesetzt. Daher habe ich mein Script hier mal aufgeschrieben und wollte fragen wie es in meinem Fall sein muss. Ich hatte versucht es mit Client ID´s zu probieren aber so funktioniert es auch nicht hoffentlich könnt ihr mir hier helfen. Danke

PHP Code:
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include <mysql.au3>
#include <md5.au3>
#include "Packets.au3"

Global $Resv,$sResv,$true "0",$false "0",$ban "0",$Verbindung,$Edit1,$sSocket,$x 0,$ID 0

$MaxConnect 
3
Global $Verbindung[$MaxConnect]

TCPStartup()
$name TCPNameToIP("")
$Socket TCPListen($name7294$MaxConnect)
If @
error Then
    MsgBox
(0,"ERROR","[Server] Fehler beim erstellen des Sockets")
    
Sleep(2500)
    Exit
EndIf

If 
Not FileExists(@ScriptDir&"\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt") Then
    DirCreate(@ScriptDir&"
\log")
    FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","")
EndIf

FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogStart Server")

Opt("
GUIOnEventMode",1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Auth Server Konsole", 536, 320, 192, 124)
$Edit1 = GUICtrlCreateEdit("", 0, 0, 529, 313, BitOR($GUI_SS_DEFAULT_EDIT,$ES_READONLY))
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###

GUISetOnEvent(
$GUI_EVENT_CLOSE,"_Exit")

Dim 
$Verbindung[$MaxConnect]
For 
$x = 0 To UBound($Verbindung) - 1
    
$Verbindung[$x] = -1
Next

 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogServer IP Adresse"&$name)
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogServer IP Adresse"&$name&@CRLF)
 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogReady for Connections!")
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogReady for Connections!"&@CRLF)

While 1
    _Check_Packets()
    Sleep(250)
WEnd

Func _Check_Packets()
    For 
$x = 0 To UBound($Verbindung) - 1
        If 
$Verbindung[$x] = -1 Then
            
$Verbindung[$x] = TCPAccept($Socket)
        EndIf

        If 
$Verbindung[$x] <> -1 Then
            
$Resv = TCPRecv($Verbindung[$x], 2048)

            If @error Then
                TCPCloseSocket(
$Verbindung[$x])
                
$Verbindung[$x] = -1
                _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[Log] @error Flag/Client disconnected")
                FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [Log] @error Flag/Client disconnected"&@CRLF)
            EndIf
            
$sResv = StringSplit($Resv,"|")

        If 
$Resv <> "" Then
            If StringInStr(
$Resv,$Connected_Req) And $sResv[1] == $Connected_Req Then
                _Handle_Connected_Client_Req()
            ElseIf 
$Resv = $Disconnected_Client_Req Then
                _Handle_Disconnect_Client_Req()
            ElseIf StringInStr(
$Resv,$Login_Req) And $sResv[1] == $Login_Req Then
                _Handle_Login_Req()
            EndIf
        EndIf
        EndIf
    Next
EndFunc

Func _setdata(
$String)
    Global 
$DataString
    
$DataString = $DataString&$String&@CRLF
    GUICtrlSetData(
$Edit1,$DataString)
    _GUICtrlEdit_LineScroll(
$Edit1, 0, _GUICtrlEdit_GetLineCount($Edit1))
EndFunc

Func _Exit()
For 
$y = 0 To UBound($Verbindung) - 1
    If 
$Verbindung[$y] <> -1 Then
    TCPSend(
$Verbindung[$y],$Shutdown_Server_Ack)
    TCPCloseSocket(
$Verbindung[$y])
    EndIf
Next
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogShutdown Server"&@CRLF)
Exit
EndFunc

Func _Handle_Login_Req()
    
$Username = "root"
    
$password = ""
    
$Database = "project coventry auth"
    
$Server = "localhost"
    
$_Mysql_Connect = _MySQLConnect($Username,$password,$Database,$Server)
    
$_mysql_Username = _GetColVals($_Mysql_Connect,"accounts","Username")
    
$_mysql_Password = _GetColVals($_Mysql_Connect,"accounts","Password")
    
$_mysql_Banned =  _GetColVals($_Mysql_Connect, "accounts", "Banned")

For 
$numbers = 1 To $_mysql_Username[0]
    If 
$sResv[2] == $_mysql_Username[$numbers] And $sResv[3] == $_mysql_Password[$numbers] Then
        
$true =+ "1"
    Else
        
$false =+ "1"
    EndIf
Next

For 
$banned = 1 To $_mysql_Username[0]
    If 
$_mysql_Banned[$banned] == "0" And $sResv[2] == $_mysql_Username[$banned] Then
        
$ban =+ "0"
    ElseIf 
$_mysql_Banned[$banned] == "1" And $sResv[2] == $_mysql_Username[$banned] Then
        
$ban =+ "1"
    EndIf
Next

If 
$true == "1" And $ban == "0" Then
For 
$x = 0 To UBound($Verbindung) - 1
If 
$Verbindung[$x] <> -1 Then
TCPSend(
$Verbindung[$x],$Login_Ack_Succed)
ExitLoop
EndIf
Next
 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogLogin succedUser"&$sResv[2])
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogLogin succedUser"&$sResv[2]&@CRLF)
$true = "0"
$false = "0"
$ban = "0"

ElseIf 
$false >= "1" And $ban == "0" Then
For 
$x = 0 To UBound($Verbindung) - 1
If 
$Verbindung[$x] <> -1 Then
TCPSend(
$Verbindung[$x],$Login_Ack_Failed)
ExitLoop
EndIf
Next
 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogLogin error... non exist account or false ID or PWUser"&$sResv[2])
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogLogin error... non exist account or false ID or PWUser"&$sResv[2]&@CRLF)
$true = "0"
$false = "0"
$ban = "0"

ElseIf 
$ban >= "1" Then
For 
$x = 0 To UBound($Verbindung) - 1
If 
$Verbindung[$x] <> -1 Then
TCPSend(
$Verbindung[$x],$Login_Ack_Banned)
ExitLoop
EndIf
Next
 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogLogin failure cause banned accountUser"&$sResv[2])
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogLogin failure cause banned accountUser"&$sResv[2]&@CRLF)
$true = "0"
$false = "0"
$ban = "0"

Else
For 
$x = 0 To UBound($Verbindung) - 1
If 
$Verbindung[$x] <> -1 Then
TCPSend(
$Verbindung[$x],$Login_Ack_Req_Failed)
ExitLoop
EndIf
Next
 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogLogin Req failedUser"&$sResv[2])
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogLogin Req failedUser"&$sResv[2]&@CRLF)
$true = "0"
$false = "0"
$ban = "0"

EndIf


    _MySQLEnd(
$_Mysql_Connect)
EndFunc

Func _Handle_Disconnect_Client_Req()
    For 
$x = 0 To UBound($Verbindung) - 1
    TCPSend(
$Verbindung[$x],$Disconnected_Client_Ack)
    TCPCloseSocket(
$Verbindung[$x])
    
$Verbindung[$x] = -1
Next

    If 
$sResv[1] == "1" Then
            
$ID = $sResv[1] - "1"
ElseIf 
$sResv[1] == "2" Then
            
$ID = $sResv[1] - "1"
ElseIf 
$sResv[1] == "3" Then
            
$ID = $sResv[1] - "1"
    EndIf

 _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogClient DisconnectedClient ID"&$ID)
FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogClient DisconnectedClient ID"&$ID&@CRLF)
EndFunc

Func _Handle_Connected_Client_Req()
    
$ID = $ID + "1"
    For 
$x = 0 To UBound($Verbindung) - 1
    TCPSend(
$Verbindung[$x],$Connected_Ack&"|"&$ID)
    Next
     _setdata("
["&@MDAY&"."&@MON&"."&@YEAR&"] ["&@HOUR&":"&@MIN&"] | "&"[LogClient ConnectedClient ID"&$ID&" Computername"&$sResv[2])
    FileWrite(@ScriptDir&"
\log\"&@MDAY&"_"&@MON&"_"&@YEAR&"_log.txt","["&@HOUR&":"&@MIN&"] [LogClient ConnectedClient ID"&$ID&" Computername"&$sResv[2]&@CRLF)
EndFunc 
mfg golle12
01/05/2015 07:19 YatoDev#7
[Only registered and activated users can see links. Click Here To Register...]

da siehst du wie man erfolgreich eine verbindung öffnet und mehrere clients haben kann(ja wird da nicht genutzt könnte aber^^)