UDP sockets - again

Alex Tweedly alex at tweedly.net
Mon Feb 28 11:23:05 EST 2005

John Rule wrote:

>	I think the inconsistency lies in the lack of documentation
>regarding 'when' to use the 'with message' and 'how' RunRev is calling these
>(or possibly this is a bug). For example:
The documentation for UDP sockets is pretty sparse (or indeed, totally 
missing, and trying to use the existing docs is near impossible, because 
the differences between TCP and UDP sockets are quite significant).
Dar Scott provided me with lots of help a while ago - you may find more 
useful info in the email archives (around September).

Summary (of what worked for me - may be other ways)

1.To accept packets from others (i.e. be a server), then you do :

>   -- note this command name is misleading
>   -- for UDP, the "accept" simply registers this object to receive 
> packets on this port
>   --   and sets up the callback function to call when such a packet 
> arrives
>   repeat for each word W in lPorts
>     accept datagram connections on port W with message "gotPacket"
>   end repeat

and then the handler "gotPacket" will be called with each arriving 
packet. In this case here, I simply reply to it ..

> -- Server mode handlers
> on gotPacket pHostPort, pData, pSock
>   local tHostPort
>   mylog "Packet arrived from" && pHostPort && "on my socket" && pSock
>   mylog "   contents:" && pData
>   open datagram socket to pHostPort
>   write "reply with " & pData to socket pHostPort
>   close socket pHostPort
> end gotPacket

2. To be a client:

>   -- open datagram socket: UDP is connectionless, so no network activity
>   -- is required for this open - hence it will complete immediately.
>   -- the message callback is used to receive any replies to packets 
> sent over this socket
>   open datagram socket to lHostPort with message "gotReplyPacket"

and then this "gotReplyPacket" will be called for any packets replied to 
as above; in my case

> -- Client mode handlers
> on gotReplyPacket pOtherOne
>   mylog "Packet arrived" && paramCount()
>   repeat with i=1 to paramCount()
>     mylog i && ":" && param(i)
>   end repeat
> end gotReplyPacket
That works for me - though I haven't tested it in any high-stress 
environment - it's been PC to PC, for "chat"-like apps, nothing that 
would send, for instance, a stream of back-to-back packets.

>	The handler "getData" is not called everytime, and the parameters
>only have data 'sometimes', but my 'sniffer' shows that my device is ALWAYS
>responding. What is the appropriate sequence, and WHEN does RunRev call
>these 'with message' handlers?! I am getting unreliable results using
>	Logically, you would think that once I instruct the handler to
>'read' from a UDP socket whenever it gets data (i.e. I have set the callback
>handler), it should ALWAYS call this handler when data is received on that
>open udp socket.
I don't have any code that reads from a UDP socket (that's not to say it 
can't be done - but all my code uses handles as in my examples above).

> Or, when I write data to an open udp socket with a handler
>message, if the destination socket responds with data, the handler should be
>called immediately. It does not ALWAYS work this way, but it is close, so I
>believe there is a problem.
There is no need (and probably no point in having) a "with callback" on 
UDP writes.

TCP sockets can be "blocked" because we've reached the maximum number of 
outstanding bytes, and cannot send any more until the remote system has 
received (and ACKed) some of what we've already sent; hence there may be 
a significant delay before the data can be sent - so rather than wait 
for that, you can pass in the callback handler, continue working and 
later be told when the data has gone.

UDP has no such issues - so the only delay possible would be network 
buffering (e.g. if you were sending to a very slow line). The call back 
function in the write should be called immediately - it has nothing to 
do with the remote system, and nothing to do with any response having 
been received.

>I do not have issues with regular sockets, just datagram sockets...
>Here are my questions that I cannot find an answer to in the documentation:
>- Once the "getData" handler is set, how often is it called?
Should be called every time a packet is received for that socket

>- If I write to an open UPD socket with a handler message, is the handler
>called 'anytime' data is received, or only for that call (i.e. am I setting
>some internal function pointer)?
question doesn't compute .... data received is passed to the handler 
specified in either a
   "accept connections"
or an
  "open datagram socket"

>- Is the data stored somewhere when it is received for retrieval using 'read
>from socket'?
Don't use read from socket :-)

>- Is the data accumulated? How large is the buffer? Can I set this?
Presumably, max packet size.
No (UDP is datagram oriented - so you send and/or receive single data 

>- How many parameters are there for the handlers?
For the "getpacket" handlers, 3 - host, port, data
For the "write" handler (which I suggest you don't use) - 1

>- Once I set the callback handler, is it 'always' set? Is it reset when the
>socket is closed?
When the socket is closed, there will be no more calls - irrelevant 
whether it is reset or not.
If the socket is re-opened, that will set a new callback handler

>- If I set a callback handler for ANY call (i.e. open 'with', write 'with',
>read 'with', accept 'with') is this handler going to be called for ANY data
As far as I know, for UDP you should set handlers only with open and 
accept, and (assuming you got port numbers, etc. right) those should be 
called for all data received.

>	I feel like I am shooting in the dark, and I am disappointed that
>this information is not somewhere in the docs. Withholding this info (for
>'Enterprise' or 'RevList' users) does not make me want to upgrade...it makes
>me want to look somewhere else for solutions.
I'm sure no info is being "withheld"; it's a deficiency in the docs, not 
anything being withheld.
UDP sockets are not widely used; I suspect there are only a fairly small 
number of people writing code that uses them, and they've each evolved a 
way that works for them. But on the other hand, there are a number of 
real users out there, so it can be made to work (at least in many cases).

And for all we know, you may have encountered a bug.
If the above doesn't help - feel free to email me your code I'll take a 
look over it and see if I have any suggestion

Alex Tweedly       http://www.tweedly.net

No virus found in this outgoing message.
Checked by AVG Anti-Virus.
Version: 7.0.300 / Virus Database: 266.5.1 - Release Date: 27/02/2005

More information about the use-livecode mailing list