UDP Multicast to TCP
[1/21] from: lmeyer:bltech:za at: 18-Nov-2009 6:05
Hi
This is my first post. I only discovered Rebol a couple of days ago, and
wow, I love it!
I need some help though with something that I am sure of is very basic, but
I have been struggling to get it right.
I am converting an incoming UDP stream to TCP. The TCP is forwarded to
anyone that connects to the TCP port. It works perfectly for our application
on the local PC.
Here is the code:
REBOL [ Title: "Multicast Receiver"]
mon-address: read make url! join "dns://" (read dns://)
inputmulticast: open udp://:6554
set-modes inputmulticast [multicast-groups: copy compose/deep [[239.2.0.81
(mon-address)]] ]
tcpoutput: open/direct/no-wait tcp://:4554
forever [
tcp: first tcpoutput
until [ error? try [
receive: wait inputmulticast
insert tcp copy receive
]
]
close tcp
]
The problem is that it does not work with multiple incoming requests, only
with one. The other tcp ports are able to connect, but they do not receive
any data. Only the first client session receives the data. I do not need to
wait for an input from the client to start forwarding the data, hence the
absence of the "wait tcp".
I use multiple telnet sessions to the open TCP port.
I have tried to create a server as described in
http://www.rebol.net/cookbook/recipes/0034.html but I cannot get it to work.
This cookbook example also includes the "wait waitports" which we need to
exclude as we need to push data to the client as soon as it connects.
Any input on how would you need to go about pushing a TCP data stream to
multiple connected client ports at the same time.
Thank you
Leon
[2/21] from: gschwarz:sctelco:au at: 18-Nov-2009 14:40
Welcome to the list. :-)
We all love Rebol here.
Regards,
Greg
[3/21] from: compkarori:gma:il at: 17-Nov-2009 23:54
It looks like you take the first connection and only deal with that one.
You need to keep listening on tcpoutput for other incoming connections.
You only check again when you get an error.
On Wed, Nov 18, 2009 at 5:05 PM, Leon Meyer <lmeyer-bltech.co.za> wrote:
> Hi
> This is my first post. I only discovered Rebol a couple of days ago, and
<<quoted lines omitted: 37>>
> To unsubscribe from the list, just send an email to
> lists at rebol.com with unsubscribe as the subject.
--
Graham Chiu
http://www.synapsedirect.com
Synapse - the use from anywhere EMR.
[4/21] from: petr:krenzelok:seznam:cz at: 18-Nov-2009 7:41
Hello,
here's my "multiserver" script, which I did for my friend, it is also
well commented. You need to experiment along the lines of creating a
wait-list. Events might happen both on the already established
connection side, as well as on the listener side. You need to "wait" to
all of those. And to not block, you can put also time into wait list. So
if there is no event on your ports, you get interrupted by the time
event. My script is async, non blocking ....
--------------------------------------
REBOL [
Title: "Multiserver"
Version: 0.2
Author: "Petr Krenzelok"
]
;--- open listen server in an async manner
listen-port: 9005
server: open/direct/no-wait/binary join tcp://: listen-port
print ["Server running on port: " listen-port]
;--- set-up a wait-list - rebol will wait for every item contained ...
wait-list: copy []
;--- set-up a block to store open connections in there ...
;--- along with info - remote IP, port ...
conn-list: copy []
;--- insert time and server into wait-list
insert wait-list 0.001
insert wait-list server
;--- forever= endless loop ....
forever [
event-port: wait wait-list
;--- if more events, let's pick first one (maybe not needed?)
if block? event-port [event-port: first event-port]
;--- has event happened on our listening server? (new connection request)
;--- if so, accept an event, insert the connection into wait-list
if event-port == server [
;--- accept connection ...
time: now/time/precise
connection: first server
print join "New connection from: " [connection/remote-ip ":"
connection/remote-port " at " time]
;--- append it into list of ports we wait for events to happen
on (wait-list)
insert wait-list connection
;--- append into our internal register of connections and its
parameters
insert conn-list reduce [connection connection/remote-ip
connection/remote-port]
write/append join %data- reduce [connection/remote-ip "-"
connection/remote-port".txt"]
join "New connection from: " [
connection/remote-ip ":" connection/remote-port
" at " time
newline
"---------------------------------------------------------"
newline
]
;--- uncomment to see the data in console ...
;probe connection
]
;--- if event received is not new connection, it might be data on
already existing connection
if found? conn-port: find conn-list event-port [
;--- let's copy data ...
time: now/time/precise
data: copy event-port
;--- close request (none) or real data arriving?
either none? data [
print join "Closing connection request from: " [conn-port/2 ":"
conn-port/3 " at " time]
;--- Write close even request into file ...
write/append join %data- reduce [conn-port/2 "-" conn-port/3 ".txt"]
join newline [
"---------------------------------------------------------"
newline
"Closing connection request from: "
conn-port/2 ":" conn-port/3
" at " time
newline newline
"========================================================="
newline
newline
]
close event-port
remove/part conn-port 3
][
;--- if we are here, real data arrived ...
print join "Data from: " [conn-port/2 ":" conn-port/3 " at " time]
;--- write data into file ...
write/append join %data- reduce [conn-port/2 "-" conn-port/3
.txt
] to-string data
;--- uncomment to see data printed to console
;print mold to-string data
;print mold data ; data as binary, not string
] ;end 'either
] ;end 'if
] ;end 'forever
[5/21] from: lmeyer:bltech:za at: 18-Nov-2009 9:18
Hi Graham
Yes, I believe you are right.
So I went and created a TCP Server port code as per the cookbook example:
REBOL[Title: "Port 4550"]
mon-address: read make url! join "dns://" (read dns://)
inputmulticast: open udp://:6550
set-modes inputmulticast [multicast-groups: copy compose/deep [[239.2.0.81
(mon-address)]] ]
listen: open/direct/no-wait tcp://:4550
waitports: [listen]
forever [
data: wait waitports
print "client connected"
either same? data listen [
active-port: first listen
append waitports active-port
][
insert data copy inputmulticast
]
]
There are 2 problems with this script for me:
1. Only the first tcp connection still receives the data. Subsequent
connections can access the port, but does not receive any data
2. I have to press any key (like spacebar) for the first connection to
receive data. I believe it is the "wait waitports" statement that creates
this scenario, but without it the code does not work at all.
It seems like the "insert data copy inputmulticast" is preventing any
subsequent connections from getting the data. The reason I say this is
because I only see the "client connected" message after the first
connection. For any subsequent connections the "client connected" never
appears although the clients are connected using telnet to port tcp 4550.
I am really stuck here. Do you know of anyone to assist me with this as we
would even consider paying a fee to get this sorted out?
Thank you
Leon
[6/21] from: david:may10:ntlworld at: 18-Nov-2009 7:38
Hello Leon,
Wednesday, November 18, 2009, 4:05:26 AM, you wrote:
> Hi
> This is my first post. I only discovered Rebol a couple of days ago, and
<<quoted lines omitted: 34>>
> Thank you
> Leon
welcome Lean.
it seems even after all this time the regulars have not seen fit to
make regular use of Multitasking capability's of rebol but there is
hope one day they may be convinced of its benefit inside tunneled overlays
for the general web/net use point to multi-point etc :)
you might find Alfred Began's really Old fully working rebol multitasking scripts
useful and interesting to look at
http://www.rebolfrance.info/org/articles/multicast/multicast.html
it needs translation from french to English but his rebol scripts are
generic and he did us all a favour by putting them in side a sip and
keeping it available all time time so grab them and be happy.
i really do wonder what ever happened to him and his interesting
sample code idea's for Multicast though , shame hes not around
innovating today that i can find, but i dont read french so perhaps
hes around still and we have missed masses of interesting rebol code
from him and his efforts...
heres a babblefish and a goggle translate of that page to make it
effortless for any interested readers and Multicast rebol coders, WE
NEED FAR MORE inventive working coders here that understand rebol at
its most innovative so keep up the good work ;)
http://babelfish.yahoo.com/translate_url?doit=done&tt=url&intl=1&fr=bf-home&trurl=http%3A%2F%2Fwww.rebolfrance.info%2Forg%2Farticles%2Fmulticast%2Fmulticast.html&lp=fr_en&btnTrUrl=Translate
http://translate.google.com/translate?js=y&prev=_t&hl=en&ie=UTF-8&u=http%3A%2F%2Fwww.rebolfrance.info%2Forg%2Farticles%2Fmulticast%2Fmulticast.html&sl=fr&tl=en
and finally you may also find a use for this yet again old, yet
innovative use for stuffing Multicast down the Internet pipes
ohh for the the lack of the MBONE and the innovators there that wrote such
innovations, if only they could inspire a new generation today
http://www.cdt.luth.se/~peppar/progs/mTunnel/
multicast Tunnel - mTunnel
--------------------------------------------------------------------------------
The mTunnel is an application that tunnels multicast packets over an Unicast UDP channel.
Several multicast streams can be sent over the same tunnel while the tunnel will still
only use one port.
This is useful if tunneling through a firewall.
The applications primary goal is to allow for easy tunneling of multicast over for instance
a modem and/or an ISDN connection.
The mTunnel has a built in Web-server allowing for easy access to information about current
tunnels.
This server listens by default on port 9000 on the machine where started.
The mTunnel also listens on session announcements for easier tunneling of known sessions.
If you download and install this package please send me an email! :-) (peppar-cdt.luth.se)
The latest public version is 0.3 released 980102.
README Changelog
Download: Windows UNIX
This version is NOT compatible with earlier versions of mTunnel!
I have also written two papers about this application: Paper1 - 1998 Paper2 - 1997
--
Best regards,
david mailto:david.may10-ntlworld.com
[7/21] from: sqlab:gmx at: 18-Nov-2009 9:22
Hi Leon,
you wait on a list of ports, but you feed only the first tcp port.
You should insert your data in all connected tcp ports
e.g.
foreach port waitports [
if all [
port <> listen
port <>inputmulticast
][
insert port datafromudp
]
]
Of course, I assume that you wait on your udp port too
The other way would be to use an awake function.
AR
On 18.11.2009 08:18, Leon Meyer wrote:
[8/21] from: lmeyer:bltech:za at: 18-Nov-2009 10:32
Hi David
I have actually used Alfred Began's multicast example to build our code. It
works well.
We are receiving a TCP stream from an application server, converting it to
UDP Multicast using rebcore, sending it one-way via satellite to multiple
receive sites. At the receive sites we are listening for the multicast using
rebcore and converting back to TCP Multicast. The whole chain works 100%
except for the multiple connections to the TCP port on the client side. We
are fooling the 3rd party client application in thinking it is receicing the
TCP stream directly from the 3rd party server.
If anyone is interested, here is the code for the server side converting the
incoming TCP stream to UDP Multicast:
REBOL[Title: "Port 4550"]
system/schemes/default/timeout: 72:00
listen: open/no-wait tcp://:4550
waitports: [listen]
odata: open udp://239.2.0.81:6550 ; udp broadcast port
set-modes odata [multicast-ttl: 10]
set-modes odata [multicast-interface: 192.168.20.23]
forever [
port: wait waitports
either same? port listen [
active-port: first listen
append waitports active-port
] [
incoming-from-remote: copy port
either incoming-from-remote [
insert odata incoming-from-remote
;print incoming-from-remote
] [
remove find waitports port
close port
]
]
]
[9/21] from: santilli:gabriele:gmai:l at: 18-Nov-2009 11:12
On Wed, Nov 18, 2009 at 5:05 AM, Leon Meyer <lmeyer-bltech.co.za> wrote:
> Here is the code:
I'd do it this way:
> REBOL [ Title: "Multicast Receiver"]
>
> mon-address: read make url! join "dns://" (read dns://)
> inputmulticast: open udp://:6554
> set-modes inputmulticast [multicast-groups: copy compose/deep [[239.2.0.81
> (mon-address)]] ]
listen: open/direct/no-wait tcp://:4554
; copy not really needed here,
; but just in case you move this to a function for eg.
output-ports: copy []
forever [
port: wait [listen inputmulticast]
case [
port = listen [
; we got a new connection
; let's add it to the list of output ports
append output-ports first listen
]
'else [
; some data incoming
data: copy inputmulticast
foreach port output-ports [
insert port data
]
]
]
]
(You'll need to also handle the case of any of your output-ports being
closed, and you'll probably want to figure out a way to tell the
server to quit, etc.)
[10/21] from: petr:krenzelok:seznam:cz at: 18-Nov-2009 11:42
Hi,
I hope I am not wrong here, but you should know, that in R2, you
basically can work in two modes - blocking (synchronous), and non
blocking. When you open your port without /no-wait refinement, then
'copy action on port blocks. It is your case, as you issue "copy
multicast", where multicast is opened in blocking mode. In this mode,
copy waits for other side to close the connection. That might be the
reason why your code "halts". Try simple example:
Console1:
---------
server: open tcp://:9005
conn: first server ;--- here 'first blocks, waiting for connection
print copy conn ; --- here 'copy blocks, waiting for other end, to
close the connection
Console2:
client: open tcp://localhost:9005
insert client "123"
insert client "456"
;--- unless you close client, Console1 is not printing anything, it is
still being blocked ...
close client ;--- now your stuff gets printed in console1
Now try the same with server: open/no-wait tcp://:9005
The scenario changes, and you have to change your logic. You have to
wait, where possible, or you code runs out. E.g. line of "conn: first
server" will return imediatelly, so you have to change it to "conn:
first wait server" - I suggest using this logic even for blocking ports
mode, because then you save yourself a few surprises.
Also remember - in /no-wait mode, it is regular to receive empty data
buffer - there is simply no data. If you need to distinguish when port
is being closed, check for "none" value.
HTH,
-pekr-
[11/21] from: santilli:gabriele:gm:ail at: 18-Nov-2009 11:49
On Wed, Nov 18, 2009 at 11:42 AM, Petr Krenzelok
<petr.krenzelok-seznam.cz> wrote:
> I hope I am not wrong here, but you should know, that in R2, you
> basically can work in two modes - blocking (synchronous), and non
<<quoted lines omitted: 3>>
> copy waits for other side to close the connection. That might be the
> reason why your code "halts". Try simple example:
Mmm, Petr, actually, he's only copying on the UDP port after a wait,
so I don't think this would be a problem. Besides, it seems to me that
/no-wait does not work on UDP listen ports...
> Console1:
> ---------
> server: open tcp://:9005
Your assumption that UDP behaves just like TCP is so very wrong. ;)
Regards,
Gabriele.
[12/21] from: lmeyer:bltech:za at: 18-Nov-2009 13:15
Hi
Wow, this email list rock!! I have only joined this morning and the now I
have a working solution!!!
Thank you to all the guys who gave me feedback (Graham Chiu, David May, AR
from SQLLab, Petr Krenzelok, Shaun Valerio and Gabrielle Santilli).
Have a great day
Leon
[13/21] from: jblake:us:ibm at: 18-Nov-2009 8:35
Return Receipt
Your [REBOL] Re: UDP Multicast to TCP
document:
was jblake-us.ibm.com
received
by:
at: 11/18/2009 08:35:58
[14/21] from: jblake:us:ibm at: 18-Nov-2009 8:38
Return Receipt
Your [REBOL] Re: UDP Multicast to TCP
document:
was jblake-us.ibm.com
received
by:
at: 11/18/2009 08:38:21
[15/21] from: jblake:us:ibm at: 18-Nov-2009 8:40
Return Receipt
Your [REBOL] Re: UDP Multicast to TCP
document:
was jblake-us.ibm.com
received
by:
at: 11/18/2009 08:40:43
[16/21] from: jblake:us:ibm at: 18-Nov-2009 8:24
Return Receipt
Your [REBOL] UDP Multicast to TCP
document:
was jblake-us.ibm.com
received
by:
at: 11/18/2009 08:24:32
[17/21] from: peter:bjoerk:sda:ch at: 19-Nov-2009 9:09
Return Receipt
Your [REBOL] Re: UDP Multicast to TCP
document:
was received peter.bjoerk-sda.ch
by:
at: 19.11.2009 09:09:30
[18/21] from: lmeyer:bltech:za at: 19-Nov-2009 19:42
Hi
Although the TCPtoMulticast and MulticastToUDP applications are working, we
have picked up an small problem.
The Payload size of the UDP output packets after the conversion does not
seem to be exactly the same as the incoming TCP Payload size (always a
couple of bytes extra). The larger the incoming TCP payload size, the more
bytes seem to be added to the output UDP payload. We have confirmed this
using Windump (windows version of tcpdump).
For example, a 16 bytes TCP payload becomes a 17 bytes UDP payload
A 771 bytes payload becomes a 778 UDP payload. Does anyone have any idea
what could be causing the additional bytes in the UDP payload? Here is the
TCPtoUDP script:
REBOL[Title: "Port 4550"]
listen: open/no-wait tcp://:4550
waitports: [listen]
odata: open udp://239.2.0.80:6550 ; udp broadcast port
set-modes odata [multicast-ttl: 10]
set-modes odata [multicast-interface: 192.168.20.23]
forever [
port: wait waitports
either same? port listen [
active-port: first listen
append waitports active-port
] [
incoming-from-remote: copy port
either incoming-from-remote [
insert odata incoming-from-remote
;print incoming-from-remote
] [
remove find waitports port
close port
]
]
]
Thank you
Leon
PS - I have removed the "read requests" from my email now- sorry if it
caused any problems yesterday.
[19/21] from: compkarori:gma:il at: 19-Nov-2009 16:08
open/binary ?
On Fri, Nov 20, 2009 at 6:42 AM, Leon Meyer <lmeyer-bltech.co.za> wrote:
> =A0Hi
> Although the TCPtoMulticast and MulticastToUDP applications are working, we
<<quoted lines omitted: 64>>
> To unsubscribe from the list, just send an email to
> lists at rebol.com with unsubscribe as the subject.
--
Graham Chiu
http://www.synapsedirect.com
Synapse - the use from anywhere EMR.
[20/21] from: lmeyer:bltech:za at: 19-Nov-2009 21:55
Hi all
Not to answer my own question, but it seems like "open/binary/direct" now
keep the TCP and UDP payloads the same size. What is the default settings if
you specify just "open"?
Leon
[21/21] from: compkarori:gma:il at: 19-Nov-2009 16:08
open without binary does line translations.
On Fri, Nov 20, 2009 at 8:55 AM, Leon Meyer <lmeyer-bltech.co.za> wrote:
> =A0Hi all
> Not to answer my own question, but it seems like "open/binary/direct" now
<<quoted lines omitted: 78>>
> To unsubscribe from the list, just send an email to
> lists at rebol.com with unsubscribe as the subject.
--
Graham Chiu
http://www.synapsedirect.com
Synapse - the use from anywhere EMR.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted