Sign in to follow this  
Followers 0
CodeMaster Rapture

Problems with Arrays and TCP/IP

3 posts in this topic

Greetings everyone,

Been awhile since I've been in the Au3 scene. Just now getting back into it.

Anyways,

I'm working on rewriting my AutoIt MUD from scratch (lost the original source) and having some trouble with two things.

1.) It isn't able to detect multiple connections from the same IP

2.) Multiple connections will crash the server (not immediately tho).

Here is some of my source:

#cs ----------------------------------------------------------------------------

 AutoIt Version: 3.2.1.3 (beta)
 Author:         CodeMaster Rapture

 Script Function:
    Main GUI loop.

#ce ----------------------------------------------------------------------------

#include <GUI.h.au3>
#include <GUI.functions.au3>
#include <utility.functions.au3>
#include <Array.au3>

;-----------------------------------------------------------------------------------------------------------------------
If ($GUI_Main == 0) Then
    _AddLog("Fatal Error! Could not create GUI!")
    MsgBox(0,"Error","Could not create GUI!")
    _GUI_Exit()
Else
    If (GUISetState(@SW_SHOW,$GUI_Main)) Then
        _AddLog("GUI Initialized.")
    Else
        _AddLog("Fatal Error! GUI could not be shown!")
        MsgBox(0,"Error","GUI Could not be shown!")
        _GUI_Exit()
    EndIf
EndIf
;-----------------------------------------------------------------------------------------------------------------------

;-----------------------------------------------------------------------------------------------------------------------
;Initiate TCP/IP functionality:
If (TCPStartup() == 0) Then
    MsgBox(0,"Error!","Could not start TCP session. Server shutdown.")
    _AddLog("Could not start TCP session. Server shutdown.")
    _GUI_Exit()
Else
    _AddLog("TCP/IP Initialized.")
EndIf

Global Const $MainSocket = TCPListen(@IPAddress1,$Port,$MaxQueue)

If ($MainSocket == -1) Then
    MsgBox(0,"Error!","Could not create main socket for IP: " & @IPAddress1 & @CRLF & "Server shutdown.")
    _AddLog("Could not create main socket for IP: " & @IPAddress1 & @CRLF & "Server shutdown.")
    _GUI_Exit()
Else
    _AddLog("Waiting for connections on port: " & $Port)
EndIf
;-----------------------------------------------------------------------------------------------------------------------

While 1
    $GUI_Msg = GUIGetMsg()
    Switch ($GUI_Msg)
        ;Snipped some code
    EndSwitch
    
    ;Look for connection from client:
    If ($Connections[0] < $MaxConnections) Then
        Local $NewConnection = TCPAccept($MainSocket)
        If ($NewConnection > -1) Then               ;Yay, someone connected!
            Local $UserIP = SocketToIP($NewConnection)
            _AddLog("User connected: " & $UserIP & " Socket: " & $NewConnection)
            ;Check for duplicate connection:
            If (StringInStr(GUICtrlRead($GUI_Main_lst_Connections),$UserIP) <> 0) Then
                TCPSend($NewConnection,"Sorry, only one connection per IP allowed. Goodbye.")
                TCPCloseSocket($NewConnection)
            Else
                _ArrayAdd($Connections,$NewConnection)  ;Let's add them to the connection list
                $Connections[0] += 1
                GUICtrlSetData($GUI_Main_lst_Connections,$UserIP)
            EndIf
        EndIf
    EndIf
    
    ;Go thru the connections and recieve data
    If ($Connections[0] > 0) Then
        Local $iter = 1, $iter2 = 1
        For $iter = 1 To $Connections[0]
            Local $Data = TCPRecv($Connections[$iter],$MaxDataSize)
            
            ;User disconnected?
            If (@error) Then
                ;Delete all data in queue to this user (if there is any)
                If ($SendQueueSockets[0] <> $SendQueueData[0]) Then
                    MsgBox(0,"Error!","Send queue out of sync! Clearing the queue!.")
                    _ClearSendQueue()
                ElseIf ($SendQueueSockets[0] > 0) Then
                    For $iter2 = 1 To $SendQueueSockets[0]
                        If ($Connections[$iter] == $SendQueueSockets[$iter2]) Then
                            _DeleteQueueItem($iter2)
                            If ($SendQueueSockets[0] == 0) Then
                                ExitLoop
                            EndIf
                        EndIf
                    Next
                EndIf
                
                ;Delete the user
                Local $UserIP = SocketToIP($Connections[$iter])
                
                If (TCPCloseSocket($Connections[$iter]) == 0) Then
                    _AddLog("Failed to disconnect user: " & $UserIP & " Socket:" & $Connections[$iter])
                Else
                    _AddLog("User disconnected: " & $UserIP & " Socket: " & $Connections[$iter])
                EndIf
                
                GUICtrlSetData($GUI_Main_lst_Connections,StringReplace(GUICtrlRead($GUI_Main_lst_Connections),$UserIP & "|",""))
                _ArrayDelete($Connections,$iter)
                $Connections[0] -= 1
            ElseIf ($Data <> "") Then
                _AddLog("Recieved (" & $Connections[$iter] & ") :: " & $Data)
                If (StringLower($Data) == "shutdown") Then
                    _GUI_Exit()
                EndIf
            EndIf
            If (Random(1,10,1) == 1) Then
                _QueueData($Connections[$iter],Random(1,10000,1))
            EndIf
        Next
    EndIf
    
    ;Go thru the connections and send data to whomever is in queue:
    If (($Connections[0] > 0) And ($SendQueueSockets[0] > 0)) Then
        Local $iter = 1, $iter2 =1
        For $iter = 1 To $Connections[0]
            For $iter2 = 1 To $SendQueueSockets[0]
                If ($SendQueueSockets[$iter2] == $Connections[$iter]) Then
                    Local $Bytes = TCPSend($Connections[$iter],$SendQueueData[$iter2])
                    If ($Bytes > 0) Then
                        _AddLog("Sent " & $Bytes & " to user " & $Connections[$iter])
                        _DeleteQueueItem($iter2)
                        If ($SendQueueSockets[0] == 0) Then
                            ExitLoop
                        EndIf
                    Else
                        _AddLog("Failed to send data to " & $Connections[$iter])
                    EndIf
                EndIf
            Next
            If ($SendQueueSockets[0] == 0) Then
                ExitLoop
            EndIf
        Next
    Else
        _ClearSendQueue()
    EndIf
    
    Sleep(1)
WEnd

And my log shows this:

2006-10-29 09:52:55 : GUI Initialized.
2006-10-29 09:52:55 : TCP/IP Initialized.
2006-10-29 09:52:55 : Waiting for connections on port: 4000
2006-10-29 09:52:58 : User connected: 192.168.1.3 Socket: 1696
2006-10-29 09:52:58 : Sent 6 to user 1696
2006-10-29 09:52:59 : Sent 6 to user 1696
2006-10-29 09:52:59 : Sent 4 to user 1696
2006-10-29 09:52:59 : Sent 6 to user 1696
2006-10-29 09:53:00 : Sent 6 to user 1696
2006-10-29 09:53:01 : Sent 6 to user 1696
2006-10-29 09:53:01 : User connected: 192.168.1.3 Socket: 1668
2006-10-29 09:53:01 : Sent 5 to user 1668
2006-10-29 09:53:01 : Sent 6 to user 1696
2006-10-29 09:53:02 : Sent 6 to user 1696
2006-10-29 09:53:02 : Sent 6 to user 1696
2006-10-29 09:53:02 : Sent 6 to user 1696
2006-10-29 09:53:02 : Sent 6 to user 1696
2006-10-29 09:53:03 : Sent 6 to user 1696
2006-10-29 09:53:03 : Sent 6 to user 1696

And the error:

C:\***************\GUI.au3 (156) : ==> Array variable has incorrect number of subscripts or subscript dimension range exceeded.: 
If ($SendQueueSockets[$iter2] == $Connections[$iter]) Then 
If (^ ERROR
+>AutoIT3.exe ended.rc:0
>Exit code: 0   Time: 10.052

Or it will crash on the line: _QueueData($Connections[$iter],Random(1,10000,1))

I'm a little confused why it is crashing. Also, I dunno why it isn't seeing the duplicate IP address. Any clue?

Thanx,

CMR

Share this post


Link to post
Share on other sites



Here's an odd one. I found where the bug is, but I dunno why it is happening:

;Go thru the connections and send data to whomever is in queue:
    If (($Connections[0] > 0) And ($SendQueueSockets[0] > 0)) Then
        Local $iter = 1, $iter2 =1
        For $iter = 1 To $Connections[0]
            For $iter2 = 1 To $SendQueueSockets[0]
                If ($SendQueueSockets[0] < $iter2) Then
                    _AddLog("Loop exceeded queued items. Loop: " & $iter2 & " Queue:" & $SendQueueSockets[0])
                    ExitLoop
                EndIf
                If ($SendQueueSockets[$iter2] == $Connections[$iter]) Then
                    Local $Bytes = TCPSend($Connections[$iter],$SendQueueData[$iter2])
                    If ($Bytes > 0) Then
                        _AddLog("Sent " & $Bytes & " to user " & $Connections[$iter])
                        _DeleteQueueItem($iter2)
                        If ($SendQueueSockets[0] == 0) Then
                            ExitLoop
                        EndIf
                    Else
                        _AddLog("Failed to send data to " & $Connections[$iter])
                    EndIf
                EndIf
            Next
            If ($SendQueueSockets[0] == 0) Then
                ExitLoop
            EndIf
        Next
    Else
        _ClearSendQueue()
    EndIf

Log:

2006-10-29 11:05:10 : GUI Initialized.
2006-10-29 11:05:10 : TCP/IP Initialized.
2006-10-29 11:05:10 : Waiting for connections on port: 4000
2006-10-29 11:05:12 : User connected: 192.168.1.3 Socket: 1696
2006-10-29 11:05:13 : Sent 6 to user 1696
2006-10-29 11:05:13 : User connected: 192.168.1.3 Socket: 1668
2006-10-29 11:05:14 : Sent 6 to user 1668
2006-10-29 11:05:14 : Sent 6 to user 1696
2006-10-29 11:05:14 : Sent 6 to user 1696
2006-10-29 11:05:14 : Sent 6 to user 1668
2006-10-29 11:05:15 : Sent 6 to user 1696
2006-10-29 11:05:15 : Sent 6 to user 1668
2006-10-29 11:05:15 : Sent 6 to user 1696
2006-10-29 11:05:15 : Loop exceeded queued items. Loop: 2 Queue:1
2006-10-29 11:05:15 : Sent 6 to user 1668
2006-10-29 11:05:15 : Sent 6 to user 1668
2006-10-29 11:05:15 : Sent 6 to user 1668
2006-10-29 11:05:15 : Sent 5 to user 1696
2006-10-29 11:05:16 : Sent 6 to user 1696
2006-10-29 11:05:16 : Sent 6 to user 1696
2006-10-29 11:05:16 : Sent 6 to user 1668
2006-10-29 11:05:16 : Sent 5 to user 1696
2006-10-29 11:05:16 : Sent 6 to user 1696
2006-10-29 11:05:17 : Sent 6 to user 1696
2006-10-29 11:05:17 : Sent 6 to user 1696
2006-10-29 11:05:18 : Sent 6 to user 1696
2006-10-29 11:05:18 : Sent 6 to user 1696
2006-10-29 11:05:19 : Sent 6 to user 1668
2006-10-29 11:05:19 : Sent 6 to user 1696
2006-10-29 11:05:20 : Sent 6 to user 1696
2006-10-29 11:05:22 : Sent 6 to user 1696
2006-10-29 11:05:22 : Sent 6 to user 1696
2006-10-29 11:05:22 : Sent 6 to user 1668
2006-10-29 11:05:22 : Sent 6 to user 1668
2006-10-29 11:05:22 : Sent 5 to user 1668
2006-10-29 11:05:23 : Sent 6 to user 1668
2006-10-29 11:05:23 : Sent 6 to user 1668
2006-10-29 11:05:23 : Sent 6 to user 1696
2006-10-29 11:05:24 : Sent 6 to user 1696
2006-10-29 11:05:24 : Loop exceeded queued items. Loop: 2 Queue:1
2006-10-29 11:05:24 : Sent 6 to user 1668
2006-10-29 11:05:26 : Sent 6 to user 1696
2006-10-29 11:05:26 : Sent 5 to user 1696
2006-10-29 11:05:26 : Sent 5 to user 1668
2006-10-29 11:05:27 : Sent 6 to user 1696
2006-10-29 11:05:28 : Sent 6 to user 1668
2006-10-29 11:05:28 : Sent 6 to user 1668
2006-10-29 11:05:28 : Sent 6 to user 1668
2006-10-29 11:05:29 : Sent 6 to user 1696
2006-10-29 11:05:29 : Sent 6 to user 1696
2006-10-29 11:05:29 : Deleting Main GUI.
2006-10-29 11:05:29 : Main GUI deleted.
2006-10-29 11:05:29 : Kicking users.
2006-10-29 11:05:29 : Kicked user 1696 (192.168.1.3)
2006-10-29 11:05:29 : Kicked user 1668 (192.168.1.3)
2006-10-29 11:05:29 : Shutting down TCP/IP.
2006-10-29 11:05:29 : TCP/IP shutdown.
2006-10-29 11:05:29 : Program Terminated.

Maybe I should decrement $iter2 aswell? Doesn't seem like good code if I have to.

-CMR

Share this post


Link to post
Share on other sites

Ok, I fixed it. was missing a simple ExitLoop. Now, to figure out how to prevent a crash if multiple users disconnect at once...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0