Global $_ahListen[10][5] = [[1,9]]
While 1
$_hMsg = GUIGetMsg(1)
Switch $_hMsg[1]
...
EndSwitch
For $_SockIdx = 1 To $_ahListen[0][0]-1 Step 1
If $_ahListen[$_SockIdx][0] Then
$_hTmpSock = TCPAccept( $_ahListen[$_SockIdx][1] )
$_aSockClients = $_ahListen[$_SockIdx][3]
If $_hTmpSock <> -1 Then
$_aSockClients[0][0] += 1
$_uB = $_aSockClients[0][0]
ReDim $_aSockClients[$_uB+1][4]
$_aSockClients[$_uB][0] = $_hTmpSock
$_aSockClients[$_uB][1] = _SocketToIP($_hTmpSock)
$_aSockClients[$_uB][2] = ''
$_aSockClients[$_uB][3] = -1
$_ahListen[$_SockIdx][3] = $_aSockClients
$_hTmpSock = -1
_Callback_OnUserConnect( $_SockIdx, $_uB )
EndIf
For $_ClSockIdx = 1 To $_aSockClients[0][0] Step 1
$_vRecv = _PackageRecv( $_aSockClients[$_ClSockIdx][0] )
If @Error Then
_RemoveUser( $_SockIdx, $_ClSockIdx, @Error )
If Not @Error Then _
ExitLoop
ElseIf IsArray( $_vRecv ) Then
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]
_ArrayDelete( $_aClients, $_iClSock )
_GUICtrlListView_DeleteItem( GUICtrlGetHandle( $_hMain_ListView[0 ] ), $_iLW_Idx )
$_ahListen[$_iSock][3] = $_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 )
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