Puzzled by ReceiveNetworkData().

Everything else that doesn't fall into one of the other PB categories.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Puzzled by ReceiveNetworkData().

Post by srod »

Hi,

I am a little puzzled by an aspect of ReceiveNetworkData(). When used by a client without a client event loop (i.e. without using NetworkClientEvent() etc.) then this function seems to block execution in the case that the server has not sent any data and has not closed the connection.

I am puzzled because I know that PB uses non-blocking sockets.

Is this behaviour to be expected and should I thus definitely use a client event loop? The reason I ask is because, for the client, I would prefer not to use a client event loop.

Test code...

Server.

Code: Select all

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 6509

If CreateNetworkServer(0, Port)
  MessageRequester("PureBasic - Server", "Server created (Port "+Str(Port)+").", 0)
  Repeat
    Delay(1)
    SEvent = NetworkServerEvent()
    If SEvent
      ClientID = EventClient()
      Select SEvent
        Case #PB_NetworkEvent_Connect
          Debug "A new client has connected!"

        Case #PB_NetworkEvent_Disconnect
          Debug "Client has disconnected!"
          Quit = 1
    
      EndSelect
    EndIf
    
  Until Quit = 1 
  
  CloseNetworkServer(0)
Else
  MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

Client.

Code: Select all

If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
Else
  Port = 6509
  *buffer = AllocateMemory(1000)
  ConnectionID = OpenNetworkConnection("localhost", Port)
  If ConnectionID
    Debug "About to call ReceiveNetworkData() ......"
    ReceiveNetworkData(ConnectionID, *Buffer, 40)
    Debug "ReceiveNetworkData() has returned!"
    CloseNetworkConnection(ConnectionID)
  Else
    MessageRequester("PureBasic - Client", "Can't find the server (Is it launched ?).", 0)
  EndIf
EndIf
Thanks.
I may look like a mule, but I'm not a complete ass.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Puzzled by ReceiveNetworkData().

Post by Rook Zimbabwe »

Srod
This is the entire code of my SQL server for my POS

Code: Select all

code removed per srods request...
If it helps... run amuck with it! (A nod in the creds would be nice to all those who utilize it!)
{{removed code}}
Last edited by Rook Zimbabwe on Tue Feb 23, 2010 8:11 pm, edited 1 time in total.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

Well that is some nice looking code Rook... but it does not belong in this thread. I did not ask for any code and there is nothing in there which comes close to addressing my question.

I would appreciate it if you would remove the code and place it in a separate thread as it simply gets in the way here. I am sure that there are indeed people who can make good use of what looks to be some valuable server/ODBC code, but at this time I am interested only in those who might be able to shed some light on my client question and indeed have the time to do so.

No offence intended Rook.
I may look like a mule, but I'm not a complete ass.
Fred
Administrator
Administrator
Posts: 18553
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Puzzled by ReceiveNetworkData().

Post by Fred »

You need to call ReadNetworkData() only if you got an event which tell you than some data awaits in the pipe (or the read will block).
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

Fred wrote:You need to call ReadNetworkData() only if you got an event which tell you than some data awaits in the pipe (or the read will block).
Righty-ho. That answers that one - though I guess it was kind of obvious considering that the read was indeed blocking! :) Is this done at the api level Fred? The reason I ask is that well, PB uses non-blocking sockets which is why I imagined that ReadNetworkData() would never block, even if there was no data to read.

Thanks Fred.
I may look like a mule, but I'm not a complete ass.
User avatar
idle
Always Here
Always Here
Posts: 6238
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Puzzled by ReceiveNetworkData().

Post by idle »

maybe just bung the client event loop in a thread with an invisible window and use a callback.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Puzzled by ReceiveNetworkData().

Post by Rook Zimbabwe »

Actully srod if you had a glance at it I use that in both the server and client side... in the events...

I do encode the string of data that gets recieved so the program or server knows what to do with it.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

idle wrote:maybe just bung the client event loop in a thread with an invisible window and use a callback.
This is a cross-platform server! :wink: I can work with a client event loop okay, not a problem, even if I had originally attempted to avoid it.

Rook wrote:I do encode the string of data that gets recieved so the program or server knows what to do with it.

Posted: Tue Feb 23, 2010 19:12
Already have that covered. Your code doesn't address the blocking nature of ReceiveNetworkData() under the circumstances described above which is why, with no disrespect intended, the code didn't belong here. :wink: To be honest Rook, that code of yours deserves it's own thread anyhow as it looks very good indeed.
I may look like a mule, but I'm not a complete ass.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Puzzled by ReceiveNetworkData().

Post by Rook Zimbabwe »

Thanks SRod... I appreciate the nice compliment :D

I was also attempting to show where I handled the recieve events... (and as a side HOW) because i didn't want extraneous info pings to the server (I did change them in the examples FYI!) 8)

I had not cinsidered blocking though... hmmm... I was also considering rewriting the server using MAP when I understad it better...

(That was a int for you to write another excellent tutorial!) :wink:
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
idle
Always Here
Always Here
Posts: 6238
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Puzzled by ReceiveNetworkData().

Post by idle »

srod wrote:
idle wrote:maybe just bung the client event loop in a thread with an invisible window and use a callback.
This is a cross-platform server! :wink: I can work with a client event loop okay, not a problem, even if I had originally attempted to avoid it.


What's the issue or problems of bunging it into a thread on other OS's?
I don't know as I haven't tried! I don't think a window is needed at all
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: Puzzled by ReceiveNetworkData().

Post by Foz »

srod wrote:
idle wrote:maybe just bung the client event loop in a thread with an invisible window and use a callback.
This is a cross-platform server! :wink: I can work with a client event loop okay, not a problem, even if I had originally attempted to avoid it.
As a big cross platform fan (develop in Linux, execute in Windows) I have posted something like this:
http://www.purebasic.fr/english/viewtop ... 22#p222722

You will notice that in the example given, I've commented out the CreateThread() on the server - that was part of my test to see now many clients it can handle without threading vs with threading.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

How did it turn out with the threading? My server is multi-threaded which, whilst it is still early days, is working well. Truth is that I am not aiming for a massive number of concurrent client connections and so I am 'reasonably' confident that having one server thread per client should work okay for me.
I may look like a mule, but I'm not a complete ass.
Foz
Addict
Addict
Posts: 1359
Joined: Tue Nov 13, 2007 12:42 pm
Location: Manchester, UK

Re: Puzzled by ReceiveNetworkData().

Post by Foz »

I think I decided that running single threaded was more than adequate - I would be working with data sizes of upto 1mb, but overall on average about 2kb, which negated the need for threading. If I was going to be working with large data transfers, then threading would come into it's own.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

Okay, blocking problem solved.

Here was the problem in a nutshell.

Basically, when a client connects to my server, the server decides whether to allow the connection. E.g. has the max number of connections been reached? Can the server allocate the resources required to service the client? Can it start a new thread to service the client etc? In cases where it decides to refuse the connection, it sends the client an error code and then immediately terminates the connection server side. This is fine, except that my client was having problems receiving this notification of a connection refusal.

The problem is that I was deferring checking the return code until the client had sent an initial request to the server (which is part of the connection protocol for my library). I figured that checking the return value could wait. This puts the server in the position of having been sent data which it does not retrieve (because it is about to close the connection) and when it then sends the aforementioned error code followed by closing the connection, the client simply does not receive a #PB_NetworkEvent_Data event unless I delay the server from terminating the connection. (Hence the reason for my wishing to avoid the use of #PB_NetworkEvent_Data client-side!)

The problem is the data being sent to the server and not being retrieved. I am unsure why this should prevent the receipt of a #PB_NetworkEvent_Data event client-side without the aforementioned server delay, but the fact is that it does! :) I have now modified the client code to check for an error return immediately on being granted the connection to see if the server has terminated the connection with an error code etc. and all is well again!

Lesson painfully learned. A bit of a mine-field this networking stuff, figuring out what 'abuses' I can and cannot get away with! :)
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Puzzled by ReceiveNetworkData().

Post by srod »

Foz wrote:I think I decided that running single threaded was more than adequate - I would be working with data sizes of upto 1mb, but overall on average about 2kb, which negated the need for threading. If I was going to be working with large data transfers, then threading would come into it's own.
Makes sense. Mine could be dealing, not so much with large transfers, but potentially quite a lot of processing in response to certain client requests etc. which is why I have gone down the multi-threaded path.
I may look like a mule, but I'm not a complete ass.
Post Reply