Problem with UDP

Started by newdep, July 28, 2004, 11:06:30 AM

Previous topic - Next topic

newdep

#15
Hello Lutz,



Yes, (net-connect) works that way indeed. What is needed extra

is the (net-listen) on UDP and the solotion is made. :-)



below is exactly what  I searched... Now the (net-listen) enhancement would

be great.. Can (net-select) be used this way too ?



> (net-connect "127.0.0.1" 54000 "udp")

300

> (net-local 300)

("127.0.0.1" 1224)



Regards and thanks for the thoughts :-)



Norman.
-- (define? (Cornflakes))

Lutz

#16
net-select, net-peer, net-local and net-peek will not need the udp option, the socket receives the datagram or stream attribute during creation, after that it is just a socket and can be treated with all other functions in a normal way.



Lutz

newdep

#17
That is great Lutz, so actualy the adjustment for (net-listen) is left?



Very nice...!
-- (define? (Cornflakes))

Lutz

#18
Yes, I am leaving home now, but you get it tonight.



Lutz

newdep

#19
Hello Lutz,



version linux 8.0.16



Using the (net-send) after opening the udp sessions to the remote (not a newlisp daemon) with a (net-connect sock "ip" "udp") the connection is directly dropped localy...actualy using newlisp <> newlisp (net-send) works fine.. Is the expectation different using none newlisp <> newlisp communication?





Secondly the server site, how to grab the remote peer? -->



> (set 'listen (net-listen 5555 "" "udp"))

5

> (net-peek listen)

0

*** remote client send "hello" with (net-send)

> (net-peek listen)

5

> (net-peer listen)

nil  <--- Howto pickup remote peer port in a different way?

> (net-sessions)

()

>



Thirdly.. i think you see it already ;-) the (net-sessions) is not

updated for the "udp" trick...

Not sure if you want to implant this into the core?



 



Regards,

Norman.
-- (define? (Cornflakes))

Lutz

#20
The missing socket in the 'net-sessions' for 'net-listen' with "udp" option was an oversight and is quick to fix.



The other stuff, I have to look into it a little bit deeper. UDP with 'C' listen(), receive() and connect(), send() is something normally not done. What is used mostly with UDP is using the 'C' sendto() and revvfrom() functions. This is the way 'net-send-udp' and 'net-receive-udp' work, and it looks like getpeername() does not work on SOCK_DGRAM sockets. There is very little about all this found in books and on the internet, I will experiment and find out more about it tomorrow.



Lutz

newdep

#21
No hurries...Take your time...:-)
-- (define? (Cornflakes))

newdep

#22
Hi Lutz,



Yes sendto is often used without the connect function called befor but send

can be used also and can only work when connect is used to open the session

first.  I think this is what you already do with the current "udp" trick.. Enhancing the "udp" functionality could take a little rewrite but is generaly

the same as for tcp accept that you need an extra catch on error...



Regards, Norman.
-- (define? (Cornflakes))

Lutz

#23
Yes, I am just about to upload 8.1.0-rc1 which gets the asynchrounous UDP stuff working.



In UDP mode sockets do not contain the peer information about ip-address and port, they are part of the UDP-packet itself.



I added two new functions:



(net-receive-from socket maxsize) => (message ip-no port)



and



(net-send-to ip-no port message socket)



also (net-receive-udp ...) now returns also the sender port as last member in the list.



This is now how you set up asynchrounous UDP server/client



;===== server



(net-listen port ip-strr "udp") =>sock-no

(while (not (net-select sock-no "r" 100000)) (...))



(net-receive-from sock-no max-bytes) => (message ip-str port)



(net-sent-to ip-str port reply-msg sock-no)



; etc



;====== client



(net-connect server-ip server-port "udp") => sock-no



(net-send sock-no message)

;; or

(net-send-to server-ip server-port message sock-no)



;; poll for reply from server

(while (not (net-select sock-no "r" 100000) (...))



(net-receive sock-no max-bytes)

;; or

(net-receive-from sock-no max-bytes



; etc





Note that on the server 'net-receive-from' and 'net-send-to' are critical because the listen socket has no clue about the remote address.



On the client side both can be used because the connect binds the remote address to the socket.





Lutz

newdep

#24
You are going like the wind!

And a new release candidate And udp enhancement......:-)







Its already released i see..pfffffffff...
-- (define? (Cornflakes))

Lutz

#25
Actually it was not much work, I just had to split net-send-udp and net-receive-udp in versions with and without creating and closing the socket. What took time was testing it and writing the documentation :-)



lutz

newdep

#26
Hi Lutz,



Just out of curriosity :), why did you chose to create 2 new functions

and not create more options with existing ones?



Its just a slight thought that (net-send-to) and (net-send-udp) could have

been mixed (because net-send-udp creates a real seperation in the newlisp network functions and is very clear to the user, while i think it could confuse the user now there are 2 ways to goto Rome ;-), while just the differance in variables in the function would create the differance in behaviour...





i.e --->



(net-send-udp str-remotehost int-remoteport str-buffer [bool])

and

(net-send-to str-remotehost int-remoteport str-buffer int-socket)



only differ [bool] or int-socket so it could become -->



(net-send-udp str-remotehost int-remoteport str-buffer [int-socket] or [bool] or [ nothing ])







and for --->



(net-receive-udp int-port int-maxsize [int-microsec][str-addr-if])

and

(net-receive-from int-socket int-max-size)



differ the amount of variables and could become -->



(net-receive-udp [ int-socket int-max-size ]

                        or

                        [ int-port int-maxsize [int-microsec][str-addr-if] ])





Its just a personal taste but i like the compacked amount

of functions newlisp has and makes it with the enhancement in

the manual more logical?





What do you think?





Regards, Norman.
-- (define? (Cornflakes))

Lutz

#27
I thought about this too and internally there are really only two functions (which take socket creation/close options), but then I realized that sendto() and recvfrom() can also be used for non UDP communications, following code works perfectly:



=== SERVER

> (net-listen 1234)

1984

> (net-accept 1984)

1976

> (net-receive-from 1976 20)

("hello" "0.0.0.0" 0)   ;; shows 0.0.0.0 for default adapter

>



=== CLIENT



> (net-connect "127.0.0.1" 1234)

1956

> (net-send-to "127.0.0.1" 1234 "hello" 1956)

5



In fact in this scenario you can mix match net-send-to/net-send and net-receive-from/net-receive to your liking. This is TCP communications not UDP. Note that at the server the sender port comes as a 0,  because of TCP protocol this field is not used. Using the new functions might be faster when on small data sizes in TCP (haven't measured it yet).  For this reason I thought it was better to show the user two pairs of functions to make the difference visible.



Lutz

newdep

#28
Hello Lutz,



Yes it makes good sence and is flexible also but its also double syntaxing

for the use of tcp (the socket and the remote ip .port). Indeed a mix match position...



For tcp most people would use the way of setup a connection and then

send data to that socket/bind.. actualy with the (net-send-to) it has only

doubled the variables..for UDP its more logical because of the protocol.



It could be a fraction quicker using (net-send-to) under tcp but thats

purly internaly in newlisp and your creating a tcp alike udp ;-)



For the conventional way of tcp communication i would always choose the

bind -> sendto <- recvfrom way, because you always want to know who is on the other end of the line.... On Udp where the protocol is not depending

on stability, variations are possible and everyone knows it while using...



You could ofcaurse bring the (net-send-to) and (net-receive-from) under in variables for (net-send) and (net-send-udp) thus keeping tcp and udp seperated... On the other hand a slight enhancement in the Manual that (net-send-to) and (net-receive-from) can be used with tcp too might do the

trick, so that you have 2 real new netowrk functions not just for udp.



Regards, Norman.
-- (define? (Cornflakes))

Lutz

#29
Perhaps we need a whole new chapter in the users manual giving templates how to set up client/server code for both protocols.



By now many programmers are familiar with what you can do with TCP, but few know the importance of UDP. I ran into it when somebody asked for UDP to control video equipment and then I implemented net-send/receive-udp.



I wonder how you got involved with UDP, is it network gameing ?



What also would be great to have some 'Norman's 5-cent' stuff for UDP (innocent hint ;-))



Lutz