Global $_ahListen[10][5] = [[1,9]] ;State|Handle|Port|Clients|LW_Item
While 1
$_hMsg = GUIGetMsg(1)
Switch $_hMsg[1]
...
EndSwitch
; ---
For $_SockIdx = 1 To $_ahListen[0][0]-1 Step 1
If $_ahListen[$_SockIdx][0] Then ;Valid
$_hTmpSock = TCPAccept( $_ahListen[$_SockIdx][1] )
$_aSockClients = $_ahListen[$_SockIdx][3]
If $_hTmpSock <> -1 Then ;New user REGION
$_aSockClients[0][0] += 1 ;aClients
$_uB = $_aSockClients[0][0]
ReDim $_aSockClients[$_uB+1][4]
$_aSockClients[$_uB][0] = $_hTmpSock ;hSocket
$_aSockClients[$_uB][1] = _SocketToIP($_hTmpSock) ;sIP
$_aSockClients[$_uB][2] = '' ;Callback_onRecv
$_aSockClients[$_uB][3] = -1 ;ListView ITEM / Задается в OnUserConnect
; ---
$_ahListen[$_SockIdx][3] = $_aSockClients
$_hTmpSock = -1
; ---
_Callback_OnUserConnect( $_SockIdx, $_uB ) ;Создаем пункт в ListView
EndIf
; ---
For $_ClSockIdx = 1 To $_aSockClients[0][0] Step 1
$_vRecv = _PackageRecv( $_aSockClients[$_ClSockIdx][0] )
If @Error Then
; 1 = Not responsed | connection failure
; 2 = Bad package | connection interrupt
; 3 = Not !Success | response failure
_RemoveUser( $_SockIdx, $_ClSockIdx, @Error )
If Not @Error Then _
ExitLoop ;User removed
ElseIf IsArray( $_vRecv ) Then
; 0 = Challenge name
; 1 = Unpacked vData(!Not Array), Array = Packed
; 2 = vData Flag(Data type or other)
; 3 = Error number(integer)
Call( $_aSockClients[$_ClSockIdx][2], $_SockIdx, $_ClSockIdx, $_vRecv )
EndIf
Next
EndIf
Next
WEnd
Func _AddSocket( $_sPort, $_vUpNP = Default )
Local $_hSocket = TCPListen( @IPAddress1, Int( $_sPort ) )
Local $_aClients[1][4] = [[0]], $Idx = $_ahListen[0][0]
Local $_sMessage = 'Listening', $_bState = 1
; ---
If @Error Then
$_sMessage = 'WSA Error! Code: ' & @Error
$_bState = 0
EndIf
; ---
If $Idx <= $_ahListen[0][1] Then
$_ahListen[$Idx][0] = $_bState
$_ahListen[$Idx][1] = $_hSocket
$_ahListen[$Idx][2] = $_sPort
$_ahListen[$Idx][3] = $_aClients
; ---
$_ahListen[$Idx][4] = _GUICtrlListView_AddItem( $_hMain_ListView[3 ], $_bState, -1 )
_GUICtrlListView_AddSubItem( $_hMain_ListView[3 ], $Idx-1, $_hSocket, 1)
_GUICtrlListView_AddSubItem( $_hMain_ListView[3 ], $Idx-1, $_sPort, 2)
_GUICtrlListView_AddSubItem( $_hMain_ListView[3 ], $Idx-1, $_sMessage, 3)
_GUICtrlListView_AddSubItem( $_hMain_ListView[3 ], $Idx-1, $_vUpNP, 4)
; ---
$_ahListen[0][0] += 1
EndIf
EndFunc
Func _RemoveUser( $_iSock, $_iClSock, $_iReason = -1 )
Local $_aClients = $_ahListen[$_iSock][3], $_iLW_Idx
; ---
If IsArray( $_aClients ) And $_iClSock <= $_aClients[0][0] Then
If $_iReason >= 0 Then _
_ConsolePrint( 'Remove user [' & $_aClients[$_iClSock][1] & '], reason: ' & $_iReason )
TCPCloseSocket( $_aClients[$_iClSock][0] )
; ---
$_aClients[0][0] -= 1
$_iLW_Idx = $_aClients[$_iClSock][3] ;Client item in LW
_ArrayDelete( $_aClients, $_iClSock )
_GUICtrlListView_DeleteItem( GUICtrlGetHandle( $_hMain_ListView[0 ] ), $_iLW_Idx )
$_ahListen[$_iSock][3] = $_aClients ;Saving new aClients
; ---
For $_iSock = 1 To $_ahListen[0][0] - 1 Step 1
$_aClients = $_ahListen[$_iSock][3]
For $_iClSock = 1 To $_aClients[0][0] Step 1
If $_aClients[$_iClSock][3] > $_iLW_Idx Then
$_aClients[$_iClSock][3] -= 1
$_ahListen[$_iSock][3] = $_aClients
EndIf
Next
Next
Return True
EndIf
Return SetError( 1, 0, False )
EndFunc
Func _DelSocket( $_iSocket )
Local $_iClSock, $_aClients, $Idx, $_iLW_Idx
; ---
If $_iSocket > 0 Then
If $_ahListen[$_iSocket][0] Then
TCPCloseSocket( $_ahListen[$_iSocket][1] )
; ---
$_aClients = $_ahListen[$_iSocket][3]
For $_iClSock = 1 To $_aClients[0][0] Step 1
_RemoveUser( $_iSocket, 1, -1 ) ;ReDim, use only first element
Next
EndIf
$_iLW_Idx = $_ahListen[$_iSocket][4]
_GUICtrlListView_DeleteItem( GUICtrlGetHandle( $_hMain_ListView[3 ] ), $_iLW_Idx )
$_ahListen[0][0] -= 1
_ArrayDelete( $_ahListen, $_iSocket )
For $Idx = 1 To $_ahListen[0][0] - 1 Step 1
If $_ahListen[$Idx][4] > $_iLW_Idx Then
$_ahListen[$Idx][4] -= 1
EndIf
Next
Else
_ConsolePrint( 'Cannot delete socket[' & $_iSocket & ']!' )
Return False
EndIf
Return True
EndFunc