Trick: Network Events and WaitWindowEvent()

Share your advanced PureBasic knowledge/code with the community.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Trick: Network Events and WaitWindowEvent()

Post by BackupUser »

Code updated For 5.20+

Restored from previous forum. Originally posted by freak.

Hi All,

When programming Network Stuff, you have to call the Network Event Functions permanently to get data. So you can't use WaitWindowEvent(), and therefore put a Delay(1) in your Loop.

Now I always disliked this Solution, and now, i've finally found a better one:

There is an API-call, that makes windows Send a Message to the WindowCallback Procedure each time a Network Event occurs.

The Trick now is, to send a #WM_NULL Message, which will be compleetly ignored, but which will still cause WaitWindowEvent() to
return a Null Value. And the best thing is, for this you don't even need a Callback Procedure. It can all be done with WaitWindowEvent().

This way, you can still use WaitWindowEvent() for the GUI Stuff, and Put your Network Event Stuff in the same Loop. So no Delay(1) is needed.

Here's a short example, that explains, how it's done:

Code: Select all

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

OpenWindow(0,0,0,300,80, "Network Server", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)

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 = CreateNetworkServer(0,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(0), #WM_NULL, #FD_ALL)


;Main Loop

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      End
    Case #PB_Event_Gadget
      If EventGadget() = 1
        text.s = GetGadgetText(0)
        SendNetworkData(EventClient() , @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


; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



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

OpenWindow(0, 0, 0, 300, 400, "Network Client", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)

ListViewGadget(1, 5, 5, 290, 390)

If InitNetwork()=0: End: EndIf                       ; Initialize Network Stuff
ConnID = 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(0), #WM_NULL, #FD_ALL)


; Main Loop

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



; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

That's it, hope it's usefull to somebody...

Timo
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Manolo.

Hi Timo,
Good Work.

Manolo
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Kale.

great trick! :)

--Kale

New to PureBasic and falling in Love! :)
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by pusztry.

Sweet!!!

- Ryan


WinXP, PIII 800 MHz, 512MB RAM, SB Live 5.1, NVidia TNT 2 Ultra
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tranquil.

I posted such a x-ample long time ago using WSAAsyncRequest_() you can use a #WM_user+(your ID) to specifie a correct user created message.

But PB seems to have problems handling your network messages. Try the following:

Send datas and you will the that your message is processed. Works fine. Now resize your window (hold it down for a while) and send datas again. you will see that your WSA Message is lost and no more network operations will be processed. Dont know why. But I did not get it work till now. (See my posting in Beginners some weeks ago)

Mike

Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User
System: Windows 2000 Server, 512 MB Ram, GeForce4200 TI 128 MB DDR, Hercules Theater 6.1 DTS Sound
System 2: Mobile Pentium 4 2.4GHz 512 MB DDR GeForce4 420-32, Windows XP Home
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by pbdep.


Hi,

Using Threads is also an option on networking!

Greetings,
Norman.
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tranquil.
Originally posted by pbdep


Hi,

Using Threads is also an option on networking!

Greetings,
Norman.
Thats right but handling events in a threaded procedure isn very smart for getting a good overview over your source. Handling that in the mainloop is more smart. (My opinion) And PB uses Non-Blocking mode so threads are not realy needed here.

Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User
System: Windows 2000 Server, 512 MB Ram, GeForce4200 TI 128 MB DDR, Hercules Theater 6.1 DTS Sound
System 2: Mobile Pentium 4 2.4GHz 512 MB DDR GeForce4 420-32, Windows XP Home
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tranquil.


By the way. I saw that you do not make any errorhandling. VERY VERY importend if you do not want to lose data. I know I said that very often in this forum and this is surely the last time. :)

Check ot the thread for correctly networking in the tips & tricks section. be warned. YOU WILL LOSE DATA!!

You can not garant to receive the complete string by ONE call of receivenetworkdata(), you packet might be incomplete!! Tests on local host often works fine, but in LAN or internet your connection is much slower and it did not work! We made many tests.

On the SendNetworkData Site you MUST check the amount of realy sended datas. Its possible that the TCP/IP buffer is full and your datas are not sended! In this case sendnetworkdata() returns #WSA_Error or the ammount of sended bytes via network.

You have been warned!

Cheers
Mike

Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User
System: Windows 2000 Server, 512 MB Ram, GeForce4200 TI 128 MB DDR, Hercules Theater 6.1 DTS Sound
System 2: Mobile Pentium 4 2.4GHz 512 MB DDR GeForce4 420-32, Windows XP Home
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by freak.

> By the way. I saw that you do not make any errorhandling.

I know, but my code was only an example, i didn't want to do much errorhandling just for a short demonstration.


> Send datas and you will the that your message is processed. Works fine. Now resize your window
>(hold it down for a while) and send datas again.

About the problems with errors handeling the Messages

I didn't know about that. But maybe you can create a hidden window and use that one to send
the Messages to, so noone can resize it :)

... just a joke.

I don't know, what the real problem here is, sorry.

So this trick is useless then?

Timo
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by MrVainSCL.

Hi freak,
yes... the codesnip is nice but dont work correctly as tranquil said... esp for newbies it would be interesting to know how does it work... they will take a look to your source and code it wrong... 999times it will work but the 1000th time it will stop (dont work due fact of losing packet datas)

Just take a closer look to tranquils example posted on this forum how to code a correct working network program!!!!! We made a loooootttttt of tests here (some months) and finaly our version works EVERYTIME without any lose of datas... Taka a look and learn about it :wink:

Stay cool...


PIII450, 256MB Ram, 80GB HD + 6,4 GB, RivaTNT, DirectX8.1, SB AWE64, Win2000 + all Updates...

greetz
MrVainSCL! aka Thorsten
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by Danilo.

MrVain for president
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tranquil.

@Freak:

Sorry I did not saw your posting till yet.
I tried it with an invisible window but it does not work either.

The problem is that you only have one callback procedure for all windows. At least you need one "move & resizeable" window to communicate with the user. And if you resize or move it while appearing an network event it gets lost.

Did not figured it out now. Very mysteriois. Possible a bug in the PB WindowCallback Handler? Fred, could it be that messages got lost?

If you only open a console input in a thread and an invisible window for network events. everything works fine.



Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User
System: Windows 2000 Server, 512 MB Ram, GeForce4200 TI 128 MB DDR, Hercules Theater 6.1 DTS Sound
System 2: Mobile Pentium 4 2.4GHz 512 MB DDR GeForce4 420-32, Windows XP Home
BackupUser
PureBasic Guru
PureBasic Guru
Posts: 16777133
Joined: Tue Apr 22, 2003 7:42 pm

Post by BackupUser »

Restored from previous forum. Originally posted by tranquil.

Pool your messages in the Window Callback and everything work fine. OH GOD, THANK YOU, tonight I will pray! :o)


Again, thousend kisses to you Fred! Do you want to merry me? :)))

Mike

Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User
System: Windows 2000 Server, 512 MB Ram, GeForce4200 TI 128 MB DDR, Hercules Theater 6.1 DTS Sound
System 2: Mobile Pentium 4 2.4GHz 512 MB DDR GeForce4 420-32, Windows XP Home
Post Reply