2. Versuch - Ungültiger Speicherzugriff bei einfachem Proxy

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

2. Versuch - Ungültiger Speicherzugriff bei einfachem Proxy

Beitrag von uweb »

Ich bin dabei einen einfachen Proxy zu schreiben.
Gestern hatte ich hier schon einen Beitrag dazu geschrieben, den ich aber heute Mittag heraus genommen habe weil ich dachte ich hätte den Fehler gefunden.
In der Mittagspause hatte ich leider keine Gelegenheit das zu überprüfen.

Nun habe ich eine abgespeckte Version (ohne Threads und ohne Konsole) und bei einem Disconnect schließe ich nun sowohl Client als auch Server.
Trotzdem tritt der Fehler immer noch auf. Zumindest erleichtert diese Version es Hilfswilligen mir einen Tipp zu geben.

Da nur kurze Textnachrichten auf dem FTP-Steuerkanal unbehandelt durchgereicht werden und ich mich aus allem anderen heraus halte sollte es eigentlich einfach sein.
Der Datenkanal kann zwischen dem Client und dem Server z.T. über den Proxy, aber immer direkt aufgebaut werden.

Dass das grundsätzlich mit dem Proxy geht sehe ich bei verschiedenen Servern wenn ich den FileZilla-Client benutze daran, dass ich ein Inhaltsverzeichnis sehe.
Mehr geht dann aber auch nicht.
Mit NetDrive sehe ich noch nicht einmal das. Wenn ich mit dem FileZilla-Client die Verbindung beende und neu verbinde bekomme ich das gleiche Ergebnis wie bei NetDrive.

Und nun kommt der merkwürdige Teil (das Ergebnis) :

Code: Alles auswählen

Ungültiger Speicherzugriff. (Schreibfehler an der Adresse 8) 
in der Zeile

Code: Alles auswählen

PSEvent = NetworkServerEvent(0)
bzw. wenn ich den Debugger in der IDE einschalte und das Semikolon vor DisableDebugger entferne dann meldet PB den Fehler dort.

Da hilft alles Ausprobieren, Debuggen und Abspecken nichts. Ich finde den Fehler nicht - bin also für jede Hilfe dankbar !!!

Code: Alles auswählen

EnableExplicit
DisableDebugger

Define NetworkBufferSize.i  = 65536
Define length.i

Define ProxyIP.i 
Define ProxyPort.i 

Define ProxyServer.i ; = CreateNetworkServer - Verbindung
Define PSEvent.i

Define ProxyClient.i ; = OpenNetworkConnection - Verbindung
Define PCEvent.i

Define ConnectedClient.i ; = EventClient() - Verbindung
Define FoundFreeConnection.i
Define FoundClientConnection.i
Define i.i
Define TMC.i          ; TOO MANY CONNECTIONS

Structure strConnection
  Client.i            ; = ConnectedClient = EventClient()
  ClientIP.i          ; wird bei active mitgeteilt und ist bei passiv nicht nötig, kann auch lokal von 127.0.0.1 abweichen
  ClientMode.i        ; 0=passive  (Client fordert PASV den Datenport des Servers an)   1=active (Client gibt seinen (Daten-)PORT vor)
  ClientDataPort.i
  
  Server.i            ; = OpenNetworkConnection(ServerName$, Port [, Modus [, TimeOut [, LokaleIP$ [, LokalerPort]]]])
  ServerIP.i          ; wird bei #ClientSide mit 127.0.0.1 initialisiert und bei #ServerSide mit ProxyIP initialisiert
  ServerMode.i        ; 0=passive  (Client fordert PASV den Datenport des Servers an)   1=active (Client gibt seinen (Daten-)PORT vor)
  ServerDataPort.i
  ServerCommandPort.i ; um lokal einen Server auf einem anderen Port als 21 laufen zu lassen
  
  Status.i      ; 0=free  1=active 2=received 3=working 4=waiting 5=sent
  
  pContent.i
  length.i
EndStructure

#passive = 0
#active = 1

#free = 0
#connected = 1 ; <> #free
#received = 2
#RequestProcessing = 3 ; <> #received
#waiting = 4
#ResponseProcessing = 5 ; <> #waiting
#sent = 6               ; <> #free until client disconnected

Define MaxConnections = 255
Dim Connection.strConnection(MaxConnections)
For i = 0 To MaxConnections
  Connection(i)\pContent = AllocateMemory(NetworkBufferSize)
Next ; i

Define *NetworkBuffer = AllocateMemory(NetworkBufferSize) ; wird verwendet wenn MaxConnections eine Verarbeitung verhindert

; für den Dummy gibt est im Moment nur einen Server (127.0.0.1:21212)
ProxyIP.i = 16777343   ; entspricht MakeIPAddress(127, 0, 0, 1)
ProxyPort = 4242
For i = 0 To MaxConnections
  Connection(i)\ServerCommandPort = 21212
  Connection(i)\ServerIP = 16777343 
Next                                ; i

Define Quit = #False

;------------
InitNetwork()

ProxyServer = CreateNetworkServer(0, ProxyPort, #PB_Network_TCP|#PB_Network_IPv4,IPString(ProxyIP))
Debug "# ProxyServer "+Str(ProxyServer)+" listening on "+ IPString(ProxyIP)+":"+Str(ProxyPort)
Debug ""

While Quit = #False
  
  PSEvent = NetworkServerEvent(0)
  If PSEvent <> #PB_NetworkEvent_None
    ConnectedClient = EventClient()
    Debug "# Event-Client - "+ Str(ConnectedClient)
    
    Select PSEvent
      Case #PB_NetworkEvent_Connect ; new Client
        
        FoundFreeConnection = #False 
        For i = 0 To MaxConnections 
          If Connection(i)\Status = #free: FoundFreeConnection = #True: Break: EndIf
        Next ; i
        
        If FoundFreeConnection
          TMC = #False
          Debug "new Client "+Str(ConnectedClient)      
          ;Connection(i)\Server = OpenNetworkConnection(IPString(Connection(i)\ServerIP), Connection(i)\ServerCommandPort)
          Connection(i)\Server = OpenNetworkConnection("ftp.free.fr", 21)
          ;Connection(i)\Server = OpenNetworkConnection("ftp.cs.tu-berlin.de", 21)
          If Connection(i)\Server
            Connection(i)\Status = #waiting
            Connection(i)\Client = ConnectedClient
          Else
            Debug "Error by OpenNetworkConnection for ftp-server"
          EndIf
        Else
          SendNetworkString (ConnectedClient,"421 Too many connections. Please try later... ",#PB_Ascii)
          If TMC = #False ; TOO MANY CONNECTIONS
            Debug "TOO MANY CONNECTIONS TO HANDLE!"
            TMC = #True
          EndIf
        EndIf
        
      Case #PB_NetworkEvent_Data 
        
        FoundClientConnection = #False 
        For i = 0 To MaxConnections
          If Connection(i)\Client = ConnectedClient: FoundClientConnection = #True: Break: EndIf
        Next ; i
        
        If FoundClientConnection
          Connection(i)\length = ReceiveNetworkData(ConnectedClient, Connection(i)\pContent, NetworkBufferSize)
          If Connection(i)\length = NetworkBufferSize : Debug "ReceiveNetworkData from Client is bigger as " + Str(NetworkBufferSize) + " Bytes." 
          ElseIf Connection(i)\length = -1 : Debug "Error by ReceiveNetworkData from Client"
          Else
            Connection(i)\Status = #received
            Debug "received from Client:"
            Debug PeekS(Connection(i)\pContent, Connection(i)\length)
            Debug "------------------------"            
          EndIf
        Else
          length = ReceiveNetworkData(ConnectedClient, *NetworkBuffer, NetworkBufferSize)
          Debug "ClientConnection not found! :-(  Too many connections."
          If length = NetworkBufferSize : Debug "ReceiveNetworkData is bigger as " + Str(NetworkBufferSize) + " Bytes." 
          ElseIf length = -1 : Debug "Error by ReceiveNetworkData from Client"
          EndIf
        EndIf
        
      Case #PB_NetworkEvent_Disconnect ; client disconnected
        FoundClientConnection = #False 
        For i = 0 To MaxConnections
          If Connection(i)\Client = ConnectedClient: FoundClientConnection = #True: Break: EndIf
        Next ; i
        
        If FoundClientConnection       
          CloseNetworkConnection(ConnectedClient)
          CloseNetworkConnection(Connection(i)\Server)
          Connection(i)\Status = #free
          Connection(i)\Client = 0
          Connection(i)\Server = 0
          Debug "Client "+Str(i)+" disconnected"          
        EndIf
        
    EndSelect
    
  EndIf ; PSEvent <> #PB_NetworkEvent_None
  
  ; später werden hier die Server- und Client-Threats aufgerufen
  For i = MaxConnections To 0 Step -1
    If Connection(i)\Status = #received 
      ;Connection(i)\Status = #RequestProcessing 
      If SendNetworkData(Connection(i)\Server,Connection(i)\pContent, Connection(i)\length) <> Connection(i)\length
        Debug "Error by SendNetworkData to Server"
      EndIf
      Connection(i)\Status = #waiting 
      ; handel Server-Events and activate threads for received server-data if ServerThreadCount < MaxThreads
    ElseIf Connection(i)\Status = #waiting
      PCEvent = NetworkClientEvent(Connection(i)\Server)
      Select PCEvent
        Case  #PB_NetworkEvent_None
        Case  #PB_NetworkEvent_Data
          Connection(i)\length = ReceiveNetworkData(Connection(i)\Server, Connection(i)\pContent, NetworkBufferSize)
          If Connection(i)\length = NetworkBufferSize : Debug "ReceiveNetworkData from Server is bigger as " + Str(NetworkBufferSize) + " Bytes." 
          ElseIf Connection(i)\length = -1 : Debug "Error by ReceiveNetworkData from Server"
          Else
            Debug "received from Server:"
            Debug PeekS(Connection(i)\pContent, Connection(i)\length)
            Debug "------------------------"             
          EndIf
          ;Connection(i)\Status = #ResponseProcessing
          If SendNetworkData(Connection(i)\Client,Connection(i)\pContent, Connection(i)\length) <> Connection(i)\length
            Debug "Error by SendNetworkData to Client"
          EndIf
          Connection(i)\Status = #sent     
        Case #PB_NetworkEvent_Disconnect ; Server disconnected
          CloseNetworkConnection(Connection(i)\Client)
          CloseNetworkConnection(Connection(i)\Server)
          Connection(i)\Status = #free
          Connection(i)\Client = 0
          Connection(i)\Server = 0
          Debug "Server for Client "+Str(i)+" disconnected"
      EndSelect
    EndIf
  Next  
  
  Delay(3) ; avoid 100% CPU
Wend

; cleanup
CloseNetworkServer(0)
CloseConsole()
End

Benutzeravatar
uweb
Beiträge: 461
Registriert: 13.07.2005 08:39

Re: 2. Versuch - Ungültiger Speicherzugriff bei einfachem Pr

Beitrag von uweb »

#PB_NetworkEvent_Disconnect
Ein Client hat den Server verlassen (Verbindungstrennung). Seine zugehörige
Verbindung wird automatisch geschlossen, CloseNetworkConnection() muss für
diesen Client nicht aufgerufen werden.
must not = darf nicht
:evil:

Der Fehler wirkt zeitversetzt und ist schwer zu finden.
Antworten