Seite 1 von 1

Chat (Linked List) Frage

Verfasst: 02.02.2009 17:02
von kiki
Hallo,

Ich habe einen kleinen Chat geschrieben. Ich poste mal hier den Code, vielleicht habt ihr noch Ideen, was man daran noch verbessern kann. Manchmal klappt da nämlich was nicht.

Server:

Code: Alles auswählen

InitNetwork()
*Buffer = AllocateMemory(1000)
CreateNetworkServer(1, 6705, #PB_Network_TCP)

Structure UserDaten
Nickname.s
EndStructure 

Structure UserName
Nickname.s
EndStructure 

Structure UserID
ID.l
EndStructure 

Global NewList UserName.UserName()
Global NewList UserID.UserID()

Global UserDaten.UserDaten
Global SEvent
Global ClientID 

Repeat
    SEvent = NetworkServerEvent()
    If SEvent
      ClientID = EventClient()
      Select SEvent
      
        Case 1
        
        AddElement(UserID())
        Debug "Connect"
        Debug ClientID
        UserID()\ID.l = ClientID
        
        Case 2
        
        FreeMemory(*Buffer)
        *Buffer = AllocateMemory(1000)
        
        ReceiveNetworkData(ClientID, *Buffer, 1000)
        Meldungstext$ = PeekS(*Buffer)
        TextInhalt$ = Mid(Meldungstext$, 10, Len(Meldungstext$)-9 )
        Meldung$ = PeekS(*Buffer, 8, 0)
        
        
        If Meldung$ = "Nickname"
        AddElement(UserName())
        UserName()\Nickname.s = TextInhalt$  
        ForEach UserID()
        SendNetworkString(UserID()\ID.l, "Clearing:test")
        Delay(500)
        ForEach UserName()
        Weiter = 0
        SendNetworkString(UserID()\ID.l, "UserUser:"+UserName()\Nickname)
        Delay(500)
        Next
        Next 
        EndIf 
        
        
        If Meldung$ = "Nachrich"
        ForEach UserID()
        SendNetworkString(UserID()\ID.l, "Nachrich:"+TextInhalt$)
        Next 
        EndIf 
        
        If Meldung$ = "ExitExit"
        Ende = ClientID
        EndIf 
        
        Case 4   
        
        ForEach UserID() 
        NextElement(UserName())
        If UserID()\ID = ClientID
        DeleteElement(UserID())
        DeleteElement(UserName())
        EndIf 
        Next
        
         ForEach UserID()
        SendNetworkString(UserID()\ID.l, "Clearing:test")
        Delay(500)
        ForEach UserName()
        Weiter = 0
        SendNetworkString(UserID()\ID.l, "UserUser:"+UserName()\Nickname)
        Delay(500)
        Next
        Next 

        
          EndSelect
    EndIf
    
  Until Quit = 1 


Client:

Code: Alles auswählen

Global Nickname$

Structure ServerDaten
User.s
EndStructure 

Global ServerDaten.ServerDaten
Global ConnectionID

Down = 0
*Buffer = AllocateMemory(1000)

Procedure Haupt(dumma.l)
If OpenWindow(1, 283, 26, 480, 418, Nickname$,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
      EditorGadget(10, 10, 10, 280, 350)
      EditorGadget(11, 320, 10, 140, 350)
      StringGadget(12, 10, 380, 300, 20, "", 0)
      EndIf 
       Repeat
       
       If GetAsyncKeyState_(#VK_RETURN)
        Repeat 
        Until GetAsyncKeyState_(#VK_RETURN) = 0
         NachrText$ = GetGadgetText(12)
         SendNetworkString(ConnectionID, "Nachrich:"+NachrText$)
         SetGadgetText(12, "")
       EndIf 
       
        EventID = WaitWindowEvent(1)
       Until EventID = #PB_Event_CloseWindow
       SendNetworkString(ConnectionID, "ExitExit")
       Delay(500)
       Down = 1
EndProcedure 


Procedure Nickname(dummb.l)
  If OpenWindow(0, 383, 268, 292, 97, "New window ( 0 )",  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
      StringGadget(1, 10, 30, 280, 23, "")
      TextGadget(2, 10, 10, 85, 18, "Dein Nickname:")
      ButtonGadget(3, 110, 60, 70, 25, "OK", #PB_Button_Default | #PB_Button_Toggle)
  EndIf
  Repeat
    EventID = WaitWindowEvent()
    If EventID = #PB_Event_Gadget
      Select EventGadget()  
        Case 3
        Nickname$ = GetGadgetText(1)
        CloseWindow(0)
        Break 1
         EndSelect 
    EndIf 
  Until EventID = #PB_Event_CloseWindow
  EndProcedure 
  
Procedure Connect(dummc.l)

;- Init
Down = 0
*Buffer = AllocateMemory(1000)
InitNetwork()

Repeat 
ConnectionID = OpenNetworkConnection("127.0.0.1", 6705)
Until ConnectionID <> 0
SendNetworkString(ConnectionID, "Nickname:"+Nickname$)

Repeat 
Delay(300)
  ServerID = NetworkClientEvent(ConnectionID) 
    Select ServerID
 
      Case 2 
        Meldungstext$ = ""
        Meldung$ = ""
        TextInhalt$ = ""
        FreeMemory(*Buffer)
        *Buffer = AllocateMemory(1000)
  
        ReceiveNetworkData(ConnectionID, *Buffer, 1000)
        Meldungstext$ = PeekS(*Buffer)
        TextInhalt$ = Mid(Meldungstext$, 10, Len(Meldungstext$)-9 )
        Meldung$ = PeekS(*Buffer, 8, 0)
        
        
          If Meldung$ = "UserUser"
          ServerDaten\User.s = TextInhalt$
          AddGadgetItem(11, 0, ServerDaten\User.s, 0, 0)
          EndIf 
        
          If Meldung$ = "Clearing"
          ClearGadgetItems(11)
          EndIf 
        
          If Meldung$ = "Nachrich"
          AddGadgetItem(10, 0, TextInhalt$, 0, 0)
          EndIf 
          
          If Down = 1
          CloseNetworkConnection(ConnectionID)
          Delay(1000) 
          End 
          EndIf 
        
    EndSelect 
  
 Until Quit = 1
  
EndProcedure

Nickname(dummb.l)

CreateThread(@Connect(), 99)

Haupt(dumma.l)


Re: Chat

Verfasst: 02.02.2009 17:12
von Kiffi
kiki hat geschrieben:Manchmal klappt da nämlich was nicht.
Was klappt da manchmal nicht?
kiki hat geschrieben:vielleicht habt ihr noch Ideen, was man daran noch verbessern kann
den Code vernünftig einzurücken wäre doch schon mal ein guter Anfang.

Grüße ... Kiffi

Verfasst: 02.02.2009 17:20
von kiki
Ist schwierig zu Erklären. Aber ich versuchs mal. Also ich Füge zu dem Server "Client 1" hinzu. Dann füge ich auch "Client 2" hinzu. Wenn ich nun die Verbindung von "Client 2" unterbreche. Steht in der Liste, es gibt nur noch "Client 1". <<< Das ist richtig. Wenn aber aber stattdessen "Client 1" trenne. Steht da, immer noch, das Client 1 online wäre und Client 2 nicht.

Ich habe warscheinlich etwas an den LinkedLists Falsch gemacht.

Verfasst: 02.02.2009 18:08
von Kaeru Gaman
also, was schon mal grundsätzlich falsch ist, ist dieses:

Code: Alles auswählen

Structure UserName
Nickname.s
EndStructure

Structure UserID
ID.l
EndStructure

Global NewList UserName.UserName()
Global NewList UserID.UserID() 
zwei listen für Name und ID?
dadurch stehen die in keinerlei Beziehung zueinander, das kann doch nicht Sinn der Sache sein.
da schwebte dir wohl eher sowas vor:

Code: Alles auswählen

Structure UserInfo
  ID.l
  IP_Add.l
  Nickname.s
EndStructure
... und was das sinnvolle Einrücken betrifft, da könntest du wirklich ein bissel fleißiger sein.

ich finde jetzt auf die schnelle nicht die stelle, wo es "Client1" und "Client2" benamst...

Verfasst: 02.02.2009 18:21
von kiki
Also wenn sich ein neuer Client mit dem Server verbindet, wird folgendes gemacht:

Alte Version:

Code: Alles auswählen

 AddElement(UserID())
        UserID()\ID.l = ClientID
Neue Version:

Code: Alles auswählen

 AddElement(UserInfo())
        UserInfo()\ID.l = ClientID
Das müsste soweit richtig sein.

Als nächstes sendet der Client dem Server seinen Nicknamen. Der gesendete String sieht dass so aus: "Nickname:Manfred"

Jetzt wird die Funktion Nickname ausgeführt:

Alt:

Code: Alles auswählen

AddElement(UserName())
        UserName()\Nickname.s = TextInhalt$  
        ForEach UserID()
        ForEach UserName()
        Weiter = 0
        SendNetworkString(UserID()\ID.l, "UserUser:"+UserName()\Nickname)
        Delay(500)
        Next
        Next 

Neu:

Code: Alles auswählen

       UserInfo()\Nickname.s = TextInhalt$  
Als nächstes wird jeder Nickname an jeden Client gesendet

Code: Alles auswählen

        ForEach UserInfo()
        ForEach UserInfo()
        SendNetworkString(UserInfo()\ID.l, "UserUser:"+UserInfo()\Nickname)
        Delay(500)
        Next
        Next 
Und der Code kann ja nicht klappen, daswegen habe ich 2 Listen gemacht.

Wie soll ich es sonst schaffen, dass alle Nicknamen nacheinander an alle Clients gesendet werden.[/code]

Verfasst: 02.02.2009 22:58
von HeX0R
So:

Code: Alles auswählen

ForEach UserInfo()
	*Index = @UserInfo()
	ID     = UserInfo()\ID
	ForEach UserInfo()
		If UserInfo()\ID <> ID
			SendNetworkString(ID, "UserUser:" + UserInfo()\Nickname)
		EndIf
	Next
	ChangeCurrentElement(UserInfo(), *Index)
Next
Aber besser wäre es, das zu bündeln, sonst produzierst du nen Ar... Sack voll Daten.
Also eine Liste der Nicks am Stück senden (darauf achten, dass das Trennzeichen im Nick nicht vorkommen darf).
So in etwa:

Code: Alles auswählen

Names.s = ""
ForEach UserInfo()
	Names + UserInfo()\Nickname + ";"
Next

ForEach UserInfo()
	SendNetworkString(UserInfo()\ID, "User:" + Names)
Next