UDP to multiple pcs over internet

Hi

I was wondering if anyone could advise the best approach to this problem.

I’ve got 8 PCs connected to the internet. I’d like the PCs to be able to speak to each other directly, however this approach is problematic with udp and impossible with tcp.

So pc 1 would be connected to pcs 2,3,4,5,6,7,8

PC1 can send different messages to the other PCs using their stored ip & port.

Are broadcast and multicast in udp manager only for sending the same data to all?

Can a piece of software receive and send udp? i.e.

udp.Connect(“192.168.0.1”, 333);
udp.Bind(444);

Using ofxUDPManager is it possible to connect to multiple addresses & ports to send, and listen (bind) to multiple incoming ports?

I can only see:

  
  
	int  Send(const char* pBuff, const int iSize);  
	//all data will be sent guaranteed.  
	int  SendAll(const char* pBuff, const int iSize);  
  

Is there any way to send a buffer to a specific port & host?

Many thanks

Broadcast is only for local networks, you put a package in the network using the broadcast address and everyone listening will receive it, actually in an ethernet local network by design everyone receives everything is just that each machine just pays attention to the packages that are directed to it’s address or the broadcast address.

Multicast is for sending the same package to several computers joined to a multicast group which propagates across routers so you can use it in bigger networks than a local one.

That said you don’t really need any of this if all you want to do is communicate several computers, irc for example uses tcp and you can see everything that everyone is sending. you can use different models:

  • there’s a server, every client sends the data to the server and the server repeats it to everyone else
  • when a client connects to the server, the server sends it all the ips of all the clients then when it want to send a message it sends it to every ip. when a client disconnects the server notifies everyone.

If you need to not loose any data, i would recommend using tcp, you’ll avoid lots of headaches.

hey, thanks for the fast response.

so broadcast & multicast are no good for me.

ideally i want to get away from using a central server that all clients connect to, as
a) if that server isn’t accessible, none will work
b) sending data through the server from one client to another is yet more hops in the chain, it’ll ultimately be slow.

ultimately i want to do pixel streaming (ideally 640x480), and feel like doing it over udp/tcp might be the best way to go.

i appreciate i’d have to compress the pixels somehow, and with udp i’d have to break it up into chunks with an id etc and that i might loose some data. but i feel like udp should be the way to go, as with tcp it can hang/wait for ages if there is no connection etc?

for example, PC1 sends a ping message to all PC2, PC3, PC4, PC5 every x seconds. Likewise PC2 sends an ‘im alive’ ping to all other pcs, every x seconds and so on.

Then PC2 is ‘connected’ to PC1 so they stream pixels between them, so PC2 sends it pixels to pc1, but it also receives pixels from PC1 (think like a skype video call).

But also PC4 might be connected and sending/receiving pixels straight to PC5.

PC3 at this point isn’t doing anything with anyone, just sending its imalive ping.

So PC1 has a list locally of all host/ports of the other PCs. Internally it manages which PCs it can connect to based on the imAlive ping. By not using a central server, if any PC goes down the whole thing will still work because it can just connect to PCs that is gets a response from, rather than fail if the central parent server is down.

Does that make sense? Do you see any flaw in my approach? Do you think udp or tcp?

Thanks

as long as you don’t need to add new computers ip’s dynamically it seems ok.

about tcp/udp, if you don’t mind loosing data, udp is theoretically faster, although not that much unless you optimize things a lot and it can be a bitch. with tcp everything is taken care for you behind the scenes.

If you just want to send individual images, take a look at my ofxHttpServer, that + asynchronous requests through the new ofURLFileLoader/ofHttpUtils or similar will get you sending/receiving jpgs in almost no time. and you know if the server is up or not in case the request times out without receiving any answer

If you want to send video, then you’ll need to do something way smarter and i’ll recommend to use gstreamer, vlc or some other library for streaming

How about a third party video service? I have used influxis for live recording off a webca. I have used them on very large projects before. Or you can install FMS or red5 yourself. It is made for flash video but it is reliable and quick.

Theoretically if you can publish the stream to fms/red5, you can read that stream through quicktime on another computer (Mac = install perian). Both fms and red5 can broadcast live.

Would it be possible to circumvent the problem by using a VPN? (not exactly sure how they work though…)

@arturo

ideally i’d like to not use gstreamer / vlc / quicktime as that would mean installing additional software to make mine work. however in your experience, which of those would be better? i need to be able o upload (stream out) and download (stream in) at the same time.

so i’m trying to see if passing pixels via udp is logistically possible.

this thread is quite interesting
http://forum.openframeworks.cc/t/video-streaming-between-two-installations/3505/0

if each pixel is 3 bytes r g b. a 320x240 image = 76800 pixels = 230400 bytes / 230kb

on that post it says

yeah, udp packets have quite a small maximum size, it’s really up to the individual network components/computer system what gets allowed through but generally you want to keep each packet <4k-6k.

so lets say 5000 bytes per buffer send. / 3 = roughly 1666 pixels per udp send. 230400 total pixel bytes / 1666 per message = 138 individual message sends to send all the pixels of a 320x240 rgb image.

it also says on the thread you should wait 3ms between each udp message going out.

so 138 messages x 3ms each = 414ms per frame

thats quite slow. am i missing something here?

is it a case of compressing the pixels to use up and therefore sending less bytes via udp?

Thanks

i guess by waiting 3ms he managed to not lose data,but you don’t need to wait at all. the problem with udp is you can loose any part of the message so you can even loose the part that tells you where the frame begins and ends. if you use udp you’ll need to make sure that at least some part is always received by implementing some kind of acknowledgement protocol so you know from which frame the data you are receiving is.

from what i’ve tested vlc has better support for standard streaming, so you can probably use vlc as the sender and the normal ofVideoPlayer as the receiver. with gstreamer, both ends needs to use gstreamer

and yes compression can help in case you have small bandwith but it will also make it harder if some parts are lost

thanks arturo.

whats the status of vlc in OFW? (im on windows).

this from 2008?
http://forum.openframeworks.cc/t/ofxvlc/1204/0

yes, i was trying to find a solution for linux videoplayer but vlc was too slow when scrubbing or changing speed so i finally went with gstreamer. the api as far as i remember was pretty easy.

you can simultanaously broadcast udp from each node on same port, but then of course you’ll have to identify what’s coming from what on arrival.
i presume the 1 port per PC approach might be better.
i think that the spread of your broadcast is determined by your subnet, which will stop you hitting the internet.

i did some tests with using vlc to stream app contents on windows on a LAN (vlc can also use screenshot and camera devices as input, so you often only need to integrate the output into your app). there’s definite latency if you’ve got a lot of data, you get compression artifacts, and CPU usage goes to the roof (even for 1 XGA stream a core2duo was pretty full).

my first suggestion would be to do some simple YUV2 compression (8 bit Y, 4 bit U, 4 bit V) which reduces your pixel size from 3 bytes to 2 bytes. This is quick, and should be simple to decode in a shader. then tag your packets.

give each packet a 5 byte header (uint32 frame index, uint8 pixel offset index)
then presuming 5kB packets, that’s 123 packets per frame
i.e. you can index each packet’s position within the frame with one byte
and index each frame with 4 bytes (could be less, 2 bytes gives you 18 hours of indexes)

multicast into a ring buffer input on each machine

i’m not sure how well the existing ofxUDPManager would deal with all this
it’s probably better to hack it a bit to make it more focused on your task.

i’d suggest doing some speed tests with vlc (or other) before considering an external lib
since each machine is only encoding 1 stream it’ll probably be breezy
perhaps run it out on the machines all decoding each others stream and look at the CPU usage with different codecs / bitrates
also note that libVLC is GPL.

elliot