ClientID()/Socket -> Rückgabewert?

Fragen und Bugreports zur PureBasic 4.0-Beta.
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

Betreff Serverseitig Verbindung beenden:

1. Hatte schon mal irgendwann im Code Archiv etwas gefunden.
Habe das Beispiel etwas geändert und die Message 2000 für FD_CLOSE verwendet.

2. TCP/IP ist schon eine Sicherungsschicht. Wozu noch einmal CRC prüfen wenn diese schon im TCP geprüft wird.
Sollte mal das Packet nicht sauber ankommen, wird es automatisch wiederholt.

Code: Alles auswählen

; English forum: 
; Author: freak
; Date: 21. January 2003
; OS: Windows
; Demo: No


; ++++++++++++++++++++++++  Network Client Example +++++++++++++++++++++++++++++++

OpenWindow(0, 0, 0, 300, 400, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "Network Client")
CreateGadgetList(WindowID())
ListViewGadget(1, 5, 5, 290, 390)

If InitNetwork()=0: End: EndIf                       ; Initialize Network Stuff
ConnID.l = OpenNetworkConnection("127.0.0.1",6000)
If ConnID = 0: End: EndIf

; The following call will activate this Trick
;
; ConnID      : connection ID (from OpenNetworkConnection)
; WindowID()  : ID of a Window, to send the Events to.
; #WM_NULL    : The Message to be Send, if a Network Event occurs.
;               #WM_NULL will be ignored, but still causes the WaitWindowEvent() to return,
;               and then the NetworkEvent to be called.
; #FD_ALL     : Event to be send to Callback Procedure, we request them all.

#FD_ALL = #FD_READ|#FD_WRITE|#FD_OOB|#FD_ACCEPT|#FD_CONNECT|#FD_CLOSE
WSAAsyncSelect_(ConnID, WindowID(), #WM_NULL, #FD_ALL) 
WSAAsyncSelect_(ConnID, WindowID(), 2000, #FD_CLOSE) 


; Main Loop

Repeat
  r1 = WaitWindowEvent()
  If r1 = #PB_EventCloseWindow Or r1 = 2000
    End
  EndIf
  If NetworkClientEvent(ConnID) = 2
    Text.s = Space(500)
    ReceiveNetworkData(ConnID, @Text, 500)
    AddGadgetItem(1,-1,Text)  
  EndIf
ForEver



; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ExecutableFormat=Windows
; FirstLine=1
; EOF

Code: Alles auswählen

; English forum:  
; Author: freak 
; Date: 21. January 2003 
; OS: Windows 
; Demo: No 
 

; ++++++++++++++++++++++++  Network Server Example +++++++++++++++++++++++++++++++

OpenWindow(0,0,0,300,80, #PB_Window_ScreenCentered | #PB_Window_SystemMenu, "Network Server")
;von freak
; ++++++++++++++++++++++++  Network Server Example +++++++++++++++++++++++++++++++


CreateGadgetList(WindowID())
StringGadget(0, 5, 5, 290, 25, "")
ButtonGadget(1, 5, 40, 80, 25, "Send")
DisableGadget(1,1)

If InitNetwork() = 0: End: EndIf                       ; Initialize Network Stuff
SOCKET.l = CreateNetworkServer(6000) 
If SOCKET = 0: End: EndIf

; The following call will activate this Trick
;
; SOCKET      : SOCKET (or Connection ID) is returned by CreateNetworkServer()
; WindowID()  : ID of a Window, to send the Events to.
; #WM_NULL    : The Message to be Send, if a Network Event occurs.
;               #WM_NULL will be ignored, but still causes the WaitWindowEvent() to return,
;               and then the NetworkEvent to be called.
; #FD_ALL     : Event to be send to Callback Procedure, we request them all.

#FD_ALL = #FD_READ|#FD_WRITE|#FD_OOB|#FD_ACCEPT|#FD_CONNECT|#FD_CLOSE
WSAAsyncSelect_(SOCKET, WindowID(), #WM_NULL, #FD_ALL) 


;Main Loop

Repeat
  Select WaitWindowEvent()
    Case #PB_EventCloseWindow
      End
    Case #PB_EventGadget
      If EventGadgetID() = 1
        text.s = GetGadgetText(0)
        SendNetworkData(NetworkClientID(), @text, Len(text)+1)
      EndIf
  EndSelect
  
  Select NetworkServerEvent()
    Case 1
      DisableGadget(1,0)    ; user connected, enable sending.
    Case 4
      DisableGadget(1,1)    ; user disconnected, disable sending.
  EndSelect
ForEver


; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ExecutableFormat=Windows
; FirstLine=1
; EOF
FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
grapy
Beiträge: 108
Registriert: 09.09.2004 09:05

Beitrag von grapy »

2. TCP/IP ist schon eine Sicherungsschicht. Wozu noch einmal CRC prüfen wenn diese schon im TCP geprüft wird.
Sollte mal das Packet nicht sauber ankommen, wird es automatisch wiederholt.
Das bezieht sich aber nur auf die Datenpakete (eine Schicht tiefer).
Wenn da beim Zusammensetzen eins fehlt wird es tatsächlich nochmals gesendet. Nicht aber auf Protokollebene!!!

Denn, ist der Server überlastet, weißt Du nicht, ob er die Daten auch tatsächlich alle erhalten hat.
Um wirklich sicher zu sein, ob die Daten vom Server erhalten wurden, ist eine Bestätigung an den Client unumgänglich! (z.B. durch CRC-Überprüfung)
Kann der Server die Daten nicht schnell genug aus dem Buffer holen wird er sozusagen vollkommen überfahren und dann geht einiges verloren.

Gruß :mrgreen: grapy
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

TCP/IP sorgt dafür, dass die Daten ankommen. Ob sie von der Serveranwendung sauber ausgewertet werden, kannst Du auf Socket-Ebene nie garantieren. Das Bekloppte dazu in diesem Thread: Hier geht es darum, einen Verbindungsabbruch festzustellen, der sowieso beim Senden von Daten bemerkt wird... Deshalb meine Frage: Warum doppelt Arbeit machen.
Benutzeravatar
mk-soft
Beiträge: 3855
Registriert: 24.11.2004 13:12
Wohnort: Germany

Beitrag von mk-soft »

@Real,

Wieso prüfen ob Server die Verbindung beendet hat!!!

Es gibt ein Anwendungsbeispiel wo dieses sehr wichtig ist.
Denn fall hatte ich auch schon in der Praxis. Es gibt RS232/RS483 Konverter auf Ethernet. Ich hatte das Glück eine Ethernet-Comport auszuwählen welcher auch als Client arbeiten kann. Das ist nicht immer gegeben. Somit kann der fall auftretten das das Programm als Client arbeiten muss ohne irgenwelche Daten Senden zu dürfen und gleichzeitig gewärleistet sein muss das dieser alle Daten empfäng. Wenn der Server (Comport) aus irgendwelchen Gründen mal kurzfristig, z.B. Stromausfall, ausfällt, muss der Client dieses erkennen und die Verbindung selbstständig wieder aufbauen.

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

@mk-soft
Yip. das ist einer der Gründe. ZWar nicht bezüglich der Schnittstelle, aber vom Grunde her. Denn es kann nicht nur gut sein, es wird bei einigen Modulen sogar "nur" so sein, das sie die Verbindung aufbauen und dann nichts mehr machen als Daten wenn nötig empfangen und verarbeiten. Dies "muß" so laufen, weil nur so gewärleistet sein kann, daß auch alle "User" hinter einer Firewall usw. korrekt laufen (und natürlich aus anderen Gründen). Wenn das mit TCP/IP nicht gehen sollte, dann ist das dumm, aber hauptsache ich weiß es.

@real
Das ist doch nicht bekloppt. Nicht nur wie es die Begründung von mk-soft aussagt, sondern auch weil nicht stimmt was du sagst. Wie kommst du darauf das man beim senden bemerken könnte (falls man überhaupt sendet) das die Verbindung abgebrochen ist?
"-1" beim senden bedeutet nur das nichts gesendet werden konnte, nicht das nicht noch was gesendet werden kann. Gerade unter Windows98 hatte ich das ständig, daß der Server einfach noch nicht dazu kam die Daten auszulesen und so der Client ständig "-1" ausgeworfen hat. Unter Windows98 können mit PB (vielleicht auch allgemein) bei mir nur ca. 5-7 (weiß gerade nicht mehr) Datenpakete bzw. Connections anliegen die noch nicht verarbeitet wurden, alle weiteren werden solange abgewiesen bis diese ausgelesen sind.
Wenn ich also was sende, so mache ich das in einer Schleife bzw. Routine die bei einem Rückgabewert von "-1" mehrfach versucht die selben daten zu senden. Es ist also keine Doppelte Arbeit.

@grapy
Da hast du natürlich recht, TCP ist ne gute Sicherungsschicht und man braucht nicht unbedingt zu prüfen ob die Daten angekommen sind. in seinem eigenem Programm aber sollte man schon ein Protokoll verwenden, welches prüft ob die Daten auch vom Server verarbeitet wurden. Aber das hängt natürlich von der Art der Anwendung ab.

Gruß
Toshy
1. Win10
PB6.1
real
Beiträge: 468
Registriert: 05.10.2004 14:43

Beitrag von real »

Wenn Du ein -1 beim Versenden erhälst kannst Du über WSAGetLastError() herausfinden, warum das Versenden schiefgegangen ist. Anhand des gemeldeten Fehlers weißt Du, ob der Server ein Paket abgewiesen hat. Guckst Du hier: MSDN

Wenn Ihr was zur Socket-Programmierung lernen und ein wenig über die Hintergründe erfahren wollt: http://www.zotteljedi.de

Okay... Will nicht weiter stressen. :oops: Merk schon, dass ihr in jedem Fall recht habt.
Nik
Beiträge: 132
Registriert: 04.02.2005 19:57

Beitrag von Nik »

Anmerkung: Unter PB 4.xx ist ConnectionID(ClientNumber) der Socket also des gleiche wie das retrurn value von socket_ und zwar eben der benutzte socket also bei

Code: Alles auswählen

ConnNumber=OpenNetworkConnection("bla.net",80);Gibt die Connection Number als die PB interne Nummer nicht den Socket zurück

Socket=ConnectionId(ConnNumber)
www.KoMaNi.de
Eine kleine Gruppe von Hobby Programmierern, die gerade einen Instant Messenger natürlich in PureBasic schreiben.
Toshy
Beiträge: 713
Registriert: 22.03.2005 00:29
Computerausstattung: Computer und Strom vorhanden
Wohnort: LK Wolfenbüttel

Beitrag von Toshy »

Hi. Durch die Ferien hat sich mein Antwort verzögert.

@real
-1 erhält man aber nicht wenn man am Clienten nichts sendet. Wenn man nur empfängt und das ist bei mir der Fall, dann bekommt man Stundenlang nicht mit das der Server eine Verbindung geschlossen hat.

@Nik
Danke. Aber so steht das. Wie ich sehe in der hilfedatei nicht. Werde das gleich mal Andre posten.
1. Win10
PB6.1
Gesperrt