Hi,
I try to figure out this matter. I am just new to this domain so excuse me for the obvious the errors. To broadcast an IP, this seems to work: | socket | socket := Socket newUDP. socket setOption: 'SO_BROADCAST' value: true. 10 timesRepeat: [ socket sendUDPData: '10.7.2.1' toHost: #[255 255 255 255] port: 9999. (Delay forSeconds: 1) wait. ]. socket closeAndDestroy. Then I can listen from the shell: with: nc -ulk 9999 Now for the listener part, I wrote something like: | socket data | socket := Socket newUDP. socket connectTo: NetNameResolver loopBackAddress port: 9999. socket waitForConnectionFor: 2. [data := socket receiveDataTimeout: 5. data crLog] ensure: [ socket closeAndDestroy] But I got an error when connecting the socket, the debugger message is: "InvalidSocketStatusException: Socket status must Unconnected before opening a new connection" So far I don't see understand this error. Port 9999 is not in use, and running again after this error the broadcast code does not lead to an error. Any idea? Thanks Hilaire -- Dr. Geo http://drgeo.eu |
Hi Hilaire,
Check UDPSocketEchoTest for a good, simple example of using UDP sockets in Pharo. You should not do #connectTo:port: but just #setPort: and listen. HTH, Sven > On 20 May 2018, at 20:59, Hilaire <[hidden email]> wrote: > > Hi, > > I try to figure out this matter. I am just new to this domain so excuse me for the obvious the errors. > > To broadcast an IP, this seems to work: > > | socket | > > socket := Socket newUDP. > socket setOption: 'SO_BROADCAST' value: true. > 10 timesRepeat: [ > socket sendUDPData: '10.7.2.1' toHost: #[255 255 255 255] port: 9999. > (Delay forSeconds: 1) wait. > ]. > socket closeAndDestroy. > > Then I can listen from the shell: with: nc -ulk 9999 > > Now for the listener part, I wrote something like: > > | socket data | > socket := Socket newUDP. > socket connectTo: NetNameResolver loopBackAddress port: 9999. > socket waitForConnectionFor: 2. > [data := socket receiveDataTimeout: 5. > data crLog] ensure: [ socket closeAndDestroy] > > But I got an error when connecting the socket, the debugger message is: > > "InvalidSocketStatusException: Socket status must Unconnected before opening a new connection" > > So far I don't see understand this error. Port 9999 is not in use, and running again after this error the broadcast code does not lead to an error. |
Thanks Sven for the indications.
Of course I already looked at this Test, but I got lost. I looked at it again, and wrote something like: | socket data | socket := Socket newUDP. socket setPort: 9999. socket waitForConnectionFor: 2; waitForDataFor: 5 . data := Array new: 100. [socket receiveUDPDataInto: data. data crLog] ensure: [ 'Closing socket' crLog. socket closeAndDestroy] I do not have error, but a time out. I broadcast from the Linux shell: echo 10.7.2.1 | nc -ub 255.255.255.255 9999 The broadcast itself is fine as I can receive it from another shell: nc -ulk 9999 10.7.2.1 Any idea? Thanks Hilaire Le 20/05/2018 à 21:43, Sven Van Caekenberghe a écrit : > Hi Hilaire, > > Check UDPSocketEchoTest for a good, simple example of using UDP sockets in Pharo. > > You should not do #connectTo:port: but just #setPort: and listen. > > HTH, > > Sven -- Dr. Geo http://drgeo.eu |
Le 21/05/2018 à 10:56, Hilaire a écrit :
> Of course I already looked at this Test, but I got lost. I looked at > it again, and wrote something like: Sorry for the badly formated code. By the way the exception handler does not work in the code version bellow. When the ConnectionTimedOut is raised the debugger still show up and the handler is not executed. Strange. | socket data | socket := Socket newUDP. socket setPort: 9999. socket waitForDataFor: 5 . data := Array new: 100. [[socket receiveUDPDataInto: data. data crLog] on: Error do:[ 'Error, closing socket' crLog. socket closeAndDestroy]] ensure: [ 'Closing socket' crLog. socket closeAndDestroy]. -- Dr. Geo http://drgeo.eu |
Hilaire,
All this is quite tricky and can be platform dependent. What works for me (non-broadcast) is the following Pharo code for listening: socket := Socket newUDP setPort: 9999; yourself. buffer := ByteArray new: 256. { buffer. socket waitForDataFor: 60; receiveUDPDataInto: buffer }. "socket closeAndDestroy." And the following terminal code $ echo ABC | nc -u 127.0.0.1 9999 This is on macOS, latest P7. Make sure to not accidentally leave the socket in use. I can't get the broadcast sending via nc to work (like your terminal example). The -b nc option on macOS is not related to broadcasting. But I am sure broadcasting works on my local network. I am playing with Multicast DNS among other things and it works fine, I can receive/resolve .local names in Pharo. I think that is what you should do too, use mDNS. Each Mac supports that (and Linux does too, Raspberry Pi's use it frequently). My mac is called 'prometheus', so it is also known as 'prometheus.local' (like a RPi would be known as 'raspberrypi.local'). The teacher's machine could be called 'teacherpc.local'. In Pharo you then do an mDNS resolve, in the code that I am working on (still experimental), it goes like this: NeoSimplifiedDNSClient new useMulticastDNS; addressForName: 'teacherpc.local'. If all is well, you'll get a SocketAddress back. If the teacher's machine is running a web server, clients can just connect to it using that address. All this provided everybody is on the same local subnet, of course. Doing the networking magic yourself is fun, but might be more work that you expect. BTW, I believe someone did play with UDP broadcasting before, I just can't remember who/when/where. Maybe Henrik ? Sven > On 21 May 2018, at 11:17, Hilaire <[hidden email]> wrote: > > Le 21/05/2018 à 10:56, Hilaire a écrit : >> Of course I already looked at this Test, but I got lost. I looked at it again, and wrote something like: > > Sorry for the badly formated code. > By the way the exception handler does not work in the code version bellow. When the ConnectionTimedOut is raised the debugger still show up and the handler is not executed. Strange. > > | socket data | > socket := Socket newUDP. > socket setPort: 9999. > socket waitForDataFor: 5 . > data := Array new: 100. > [[socket receiveUDPDataInto: data. > data crLog] on: Error do:[ 'Error, closing socket' crLog. socket closeAndDestroy]] > ensure: [ 'Closing socket' crLog. socket closeAndDestroy]. > > > > -- > Dr. Geo > http://drgeo.eu > > > |
Sven Van Caekenberghe <[hidden email]> wrote:.
> > I can't get the broadcast sending via nc to work (like your terminal > example). The -b nc option on macOS is not related to broadcasting. Who’s allowed to broadcast? Stephan |
> On 21 May 2018, at 19:37, Stephan Eggermont <[hidden email]> wrote: > > Sven Van Caekenberghe <[hidden email]> wrote:. >> >> I can't get the broadcast sending via nc to work (like your terminal >> example). The -b nc option on macOS is not related to broadcasting. > > Who’s allowed to broadcast? Yes, I vaguely remember that Unix permissions are involved, I just don't know how this works exactly. > Stephan > > |
Noury did. He sent that on the other thread :
« Just want to point that I did some work late 2017 on UDP sockets including multicast and broadcast.
The package named 'NetworkExtras' is part of the ReusableBricks repo of my team. It has some dependencies on other packages. » It may help. I cc Noury. Cheers, Cédrick
|
In reply to this post by HilaireFernandes
HilaireFernandes wrote
> Thanks Sven for the indications. > > Of course I already looked at this Test, but I got lost. I looked at it > again, and wrote something like: > > | socket data | socket := Socket newUDP. socket setPort: 9999. > socket waitForConnectionFor: 2; waitForDataFor: 5 . data := Array > new: 100. [socket receiveUDPDataInto: data. data crLog] > ensure: [ 'Closing socket' crLog. socket closeAndDestroy] > > I do not have error, but a time out. > > Dr. Geo > http://drgeo.eu With UDP, there is no connection concept, so I'd reckon waitForConnectionFor: is what gives you a TimeOut error... Delete that, only use waitForDataFor: n , put it in a loop (so it won't stop listening until it receives a request), and you should be fine. Doesn't quite look like neither server nor client yet, the workflow should be something like: 1) server (you) starts, listening to port you're using and waitsForData: in an infinite loop. 2) client (student) starts, sends request to broadcast address/port, then waitsForData: on the socket it created. 3) broadcast server reads request, generates reply, and sends it to the originIP/port of the request 4) client receives reply, handles it, and closes socket. Cheers, Henry PS. Why use nc when you already have a working broadcast client in pharo? ;) -- Sent from: http://forum.world.st/Pharo-Smalltalk-Users-f1310670.html |
In reply to this post by cedreek
Note that the package includes tests that show that the broadcast working :-) Noury
|
In reply to this post by Henrik Sperre Johansen
Hi Henrik,
Le 22/05/2018 à 10:57, Henrik Sperre Johansen a écrit : > With UDP, there is no connection concept, so I'd reckon > waitForConnectionFor: is what gives you a TimeOut error... The #waitForConnectionFor: message seems not to be the issue. I was doing something apparently stupid: I started first the broadcast from the shell, then the listener in Pharo. Funnily I was doing it the other way when using nc to listen. Any way I will still discard #waitForConnectionFor: > Delete that, only use waitForDataFor: n , put it in a loop (so it won't stop > listening until it receives a request), and you should be fine. ok > Doesn't quite look like neither server nor client yet, the workflow should > be something like: > 1) server (you) starts, listening to port you're using and waitsForData: in > an infinite loop. > 2) client (student) starts, sends request to broadcast address/port, then > waitsForData: on the socket it created. > 3) broadcast server reads request, generates reply, and sends it to the > originIP/port of the request > 4) client receives reply, handles it, and closes socket. If I understand correctly what you suggest, student workstations initiate the broadcast to manifest interest to access My scenario initial idea was a bit more like: 1) server, teacher workstation, continuously broadcast its IP to a specific port. 2) student workstation, when they want to access teacher shares, listen to this port to get the teacher workstation IP 3) once student workstation got the ip, it stops listen for broadcast, and it connects to the to the teacher workstation http server to access the shares. Your scenario does not need a continuously broadcast... > PS. Why use nc when you already have a working broadcast client in pharo?;) Oh, just to play with one variable at a time. But seems I introduced a human factor. Thanks Hilaire -- Dr. Geo http://drgeo.eu |
In reply to this post by Noury Bouraqadi-2
I took a look of course. Thanks.
At my basic level of knowledge, I found the articles on the Pharo books and the basic Tests on Socket very helpful. Hilaire Le 23/05/2018 à 17:42, N. Bouraqadi a écrit : > Note that the package includes tests that show that the broadcast > working :-) > > Thanx Cédrick for the CC. > Noury >> On 21 May 2018, at 21:17, Cédrick Béler >> <[hidden email] >> <mailto:[hidden email]>> wrote: >> >> Noury did. He sent that on the other thread : >> >> « Just want to point that I did some work late 2017 on UDP sockets >> including multicast and broadcast. >> The package named 'NetworkExtras' is part of the ReusableBricks repo >> of my team. >> http://smalltalkhub.com/#!/~CAR/ReusableBricks >> <http://smalltalkhub.com/#%21/%7ECAR/ReusableBricks> >> It has some dependencies on other packages. » >> >> It may help. I cc Noury. -- Dr. Geo http://drgeo.eu |
Free forum by Nabble | Edit this page |