#cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.6.1 Author: Matwachich Date: 11/04/2011 Script Function: Fonctions pour faciliter la création de serveurs TCP multi-clients #ce ---------------------------------------------------------------------------- #Include-Once Global $__TCP_Sockets[1][3], $hListenSocket = -1 #cs #Region - ### EXAMPLE ### _TCP_Server_Start("127.0.0.1", 8080, 10) While 1 _TCP_Server_Process("_RecvFunc", "_NewClient", "_LostClient") Wend Func _RecvFunc($socket, $ip, $recv) ConsoleWrite($ip & ":" & @CRLF & $recv & @CRLF) EndFunc Func _NewClient($socket, $ip) ConsoleWrite("> New Connection: " & $ip & @CRLF) EndFunc Func _LostClient($socket, $ip) ConsoleWrite("> Lost Connection: " & $ip & @CRLF) EndFunc #EndRegion ### #ce ; ############################################################## ; # FUNCTION # ============================================================================================== ; Name...........: _TCP_Server_Start ; Description....: Démare un Serveur TCP ; Parameters.....: $sIp = l'adresse IP du serveur ; $iPort = Port du serveur ; $iMaxClients = Nombre maximum de clients que le serveur peut accepter ; Return values..: Succes - 1 ; Echec - 0 Et @error = -1 -> Serveur déjà démaré ; @error = 1 -> IP Invalide ; @error = 2 -> Port Invalide (déjà utilisé) ; Author.........: Matwachich ; Remarks........: ; =========================================================================================================== Func _TCP_Server_Start($sIp, $iPort, $iMaxClients = 50) If $hListenSocket <> -1 Then Return SetError(-1, 0, 0) ; --- __TCP_Init_SocketsArray($iMaxClients) ; --- TCPStartup() $hListenSocket = TCPListen($sIp, $iPort) If @error Then Return SetError(@error, 0, 0) ; --- Return 1 EndFunc ; # FUNCTION # ============================================================================================== ; Name...........: _TCP_Server_Stop ; Description....: Arrète un serveur TCP ; Parameters.....: Aucun ; Return values..: Succes - 1 ; Echec - 0 Et @error = -1 -> Le serveur n'a pas été démarer ; @error = x -> Erreur de TCPCloseSocket() ; Author.........: Matwachich ; Remarks........: ; =========================================================================================================== Func _TCP_Server_Stop() If $hListenSocket = -1 Then Return SetError(-1, 0, 0) ; --- Local $ret = TCPCloseSocket($hListenSocket) TCPShutdown() Return $ret EndFunc ; # FUNCTION # ============================================================================================== ; Name...........: _TCP_Server_Process ; Description....: Traite les evenements du serveur (Connection, deconnection, réception de données) ; Parameters.....: $sRecvFunc = Fonction à appeler lors de la réception de données ; $sNewClientFunc = Fonction à appeler lorsqu'un nouveau client se connecte ; $sLostClientFunc = Fonction à appeler Lorsqu'un client se déconnecte ; $iSleep = Valeur du Sleep() à la fin de la fonction (évite la surchage CPU) ; Return values..: Succes - Rien ; Echec - 0 Et @error = 1 -> Pas de serveur démaré ; Author.........: Matwachich ; Remarks........: Les fonctions des événements sont de la forme suivant: ; - $sRecvFunc ($hSocket, $sIp, $sReceived) ; - $sNewClientFunc ($hSocket, $sIp) ; - $sLostClientFunc ($hSocket, $sIp) ; =========================================================================================================== Func _TCP_Server_Process($sRecvFunc = "", $sNewClientFunc = "", $sLostClientFunc = "", $iSleep = 50) If $hListenSocket = -1 Then Return SetError(1, 0, 0) ; --- Local $tmp Local $hSocket = TCPAccept($hListenSocket) If Not @error And $hSocket <> -1 Then $tmp = __TCP_ArrayAdd($hSocket) Call($sNewClientFunc, $hSocket, $__TCP_Sockets[$tmp][1]) EndIf ; --- Local $recv For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] = -1 Then ContinueLoop ; --- $recv = TCPRecv($__TCP_Sockets[$i][0], 2048) If @error Then If $__TCP_Sockets[$i][0] <> -1 Then Call($sLostClientFunc, $__TCP_Sockets[$i][0], $__TCP_Sockets[$i][1]) $__TCP_Sockets[$i][0] = -1 $__TCP_Sockets[$i][1] = -1 EndIf EndIf ; --- If $recv Then $__TCP_Sockets[$i][2] &= $recv Else If $__TCP_Sockets[$i][2] <> "" Then Call($sRecvFunc, $__TCP_Sockets[$i][0], $__TCP_Sockets[$i][1], $__TCP_Sockets[$i][2]) $__TCP_Sockets[$i][2] = "" EndIf EndIf Next Sleep($iSleep) EndFunc ; # FUNCTION # ============================================================================================== ; Name...........: _TCP_Server_SocketToIp ; Description....: Retourne l'IP du client $hSocket ; Parameters.....: $hSocket = Socket du client ; Return values..: Succes = IP du client ; Echec = "" Et @error = 1 -> La socket fournie en paramètre est invalide ; Author.........: Matwachich ; Remarks........: Doit être utilisée à la place de _SocketToIP ; =========================================================================================================== Func _TCP_Server_SocketToIp($hSocket) For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] = $hSocket Then Return SetError(0, 0, $__TCP_Sockets[$i][1]) Next Return SetError(1, 0, "") EndFunc ; # FUNCTION # ============================================================================================== ; Name...........: _TCP_Server_IpToSocket ; Description....: Retourne le handle de socket correspondant à $sIp ; Parameters.....: $sIp = IP du client ; Return values..: Succes = Handle de socket du client ; Echec = "" Et @error = 1 -> L'IP fournie en paramètre est invalide ; Author.........: Matwachich ; Remarks........: ; =========================================================================================================== Func _TCP_Server_IpToSocket($sIp) For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][1] = $sIp Then Return SetError(0, 0, $__TCP_Sockets[$i][0]) Next Return SetError(1, 0, "") EndFunc ; ============================================================== ; ### Internals ; ============================================================== Func __TCP_Init_SocketsArray($iMax) ReDim $__TCP_Sockets[$iMax][3] For $i = 0 To $iMax - 1 $__TCP_Sockets[$i][0] = -1 ; hSocket $__TCP_Sockets[$i][1] = -1 ; IP $__TCP_Sockets[$i][2] = "" ; Receive Buffer Next EndFunc Func __TCP_ArrayAdd($hSocket) For $i = 0 To UBound($__TCP_Sockets) - 1 If $__TCP_Sockets[$i][0] = -1 Then $__TCP_Sockets[$i][0] = $hSocket $__TCP_Sockets[$i][1] = _SocketToIP($hSocket) $__TCP_Sockets[$i][2] = "" Return $i EndIf Next Return 0 EndFunc Func _SocketToIP($SHOCKET) Local $sockaddr, $aRet, $hDll = DllOpen("Ws2_32.dll") $sockaddr = DllStructCreate("short;ushort;uint;char[8]") $aRet = DllCall($hDll, "int", "getpeername", "int", $SHOCKET, _ "ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr)) If Not @error And $aRet[0] = 0 Then $aRet = DllCall($hDll, "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3)) If Not @error Then $aRet = $aRet[0] Else $aRet = 0 EndIf $sockaddr = 0 DllClose($hDll) Return $aRet EndFunc ;==>SocketToIP