Home All Groups Group Topic Archive Search About

how to control UDP sending Speed?

Author
16 Mar 2007 10:43 AM
Victor
Hi!
I need program a constant bitrate rate output for udp such as 5MBps or
4MBps.
The .net UDP control couldn't provide any sending speed control function.
I have try to do it manually like use asynchronism IO function such as
UDPClient.BeginSend(..)..
It's not work. the speed that i have setting as 5MBps is actually only be
controled between 3MBps~8MBps.

is it need use QOS function?


Somebody can help me please ?

Thanks

Victor Ho

Author
16 Mar 2007 1:12 PM
Peter Duniho
On Fri, 16 Mar 2007 18:43:18 +0800, Victor <vvhh2002@nospam.nospam> wrote:

> Hi!
> I need program a constant bitrate rate output for udp such as 5MBps or
> 4MBps.
> The .net UDP control couldn't provide any sending speed control function.
> I have try to do it manually like use asynchronism IO function such as
> UDPClient.BeginSend(..)..
> It's not work. the speed that i have setting as 5MBps is actually only be
> controled between 3MBps~8MBps.

What exactly are you trying to accomplish?

Generally speaking, the best you can do is achieve a target *average* 
speed.  Especially with UDP, but even with TCP (because even if you only 
send one byte at a time, unless you disable Nagle the network stack will 
coalesce your data into larger groups), groups of bytes will be sent out 
at the rated speed of the connection (usually 100Mbps on a LAN, and 
something slower on an Internet connection...128Kbps is common for cable 
modem upload speeds, for example).

It's not really practical to expect a literally constant bitrate data 
transfer for Ethernet (and for a variety of other computer communication 
links for that matter).  You have no control over the low-level hardware 
data transfer rate.  All you can do is monitor both your data transfer 
amount and the clock, and make sure you only send data as fast as your 
target is.  It sounds as though you already are doing this much, so if you 
want something better than that, you are either expecting too much, or you 
need to think about coding your data transfer at a MUCH lower level (that 
is, basically writing your own communications driver...frankly, I doubt 
you really want or need to do this).

If you can be more explicit about why it is you want to have a constant 
bitrate for your data transfer and how you've implemented it so far, it's 
possible you might get a more insightful answer than this one.  Not 
guaranteed, but at least possible.  :)

Pete
Author
17 Mar 2007 2:54 AM
Victor
Thanks, Pete
I just want program a UDP stream sending application for a IPQAM device that
is needed by Digial TV VOD Broadcast system.The speed of my server and a
IPQAM device is 10000Mbps.
The IPQAM device only can accept a constant bit rate udp TS(mpeg2 transport
stream) data stream for broadcasting TV.
I have implemented it like this:

1. implement a high performance timer by  QueryPerformanceFrequency and
QueryPerformanceCounter.
internal class HiPerfTimer
    {
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceCounter(out long
lpPerformanceCount);

        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long
lpFrequency);

        private long startTime, stopTime;
        private long freq;

        // Constructor
        public HiPerfTimer()
        {
            startTime = 0;
            stopTime = 0;

            GetFreq();
        }

        private void GetFreq()
        {
            if (QueryPerformanceFrequency(out freq) == false)
            {
                // high-performance counter not supported
                throw new Win32Exception();
            }
        }

        // Start the timer
        public void Start()
        {
            // lets do the waiting threads there work
            Thread.Sleep(0);

            QueryPerformanceCounter(out startTime);
        }

        public long GetCounter()
        {
            long Counter = 0;
            QueryPerformanceCounter(out Counter);
            return Counter;
        }

        // Stop the timer
        public void Stop()
        {
            QueryPerformanceCounter(out stopTime);
        }

        // Returns the duration of the timer (in seconds)
        public double Duration
        {
            get
            {
                GetFreq();
                return (double)(stopTime - startTime) / (double)freq;
            }
        }
        public long Freq
        {
            get
            {
                GetFreq();
                return freq;
            }
        }

        // waits for a specified number of microseconds then returns 0.
returns -1 if timing is not supported
        public int Wait(long usecs)
        {
            long end=0;
            long FLastTime=0;
            // Convert microseconds to performance counter units per move.
            QueryPerformanceCounter(out FLastTime);
            end = FLastTime + usecs * freq / 1000000;
            do
            {

                Thread.Sleep(0);
                QueryPerformanceCounter(out FLastTime);
            } while (FLastTime < end);
            FLastTime = end;
            return 0;
        }

        public int WaitT(long usecs)
        {
            long end = 0;
            long FLastTime = 0;
            // Convert microseconds to performance counter units per move.
            QueryPerformanceCounter(out FLastTime);
            end = FLastTime + usecs;
            do
            {
                Thread.Sleep(1);
                QueryPerformanceCounter(out FLastTime);
            } while (FLastTime < end);

            return 0;
        }

        //return milsec
        public long DurationL
        {
            get
            {
                GetFreq();
                return (long)((stopTime - startTime)*1000000 / freq);
            }
        }
    }

2. when i sending a buffer  i use  asynchronism IO function
UDPClient.BeginSend(..), and waiting sending complete .

        HTimer.Start();
         FIPClient.BeginSend(SendBuffer, SendBuffer.Length, new
AsyncCallback(SendCallback), FIPClient);
         SendedEvent.WaitOne();
          FSendCount += SendBuffer.Length;
          HTimer.Stop();
          DTime = HTimer.DurationL;
          if (DTime < FOneSendTimeCount) //FOneSendTimeCount is
SendBuffer.Length / Bps
          {
              DTime = FOneSendTimeCount - DTime - FLostCount;
              HTimer.WaitT(DTime);
            }


As you say, it's only be achieve  an average speed. Couldn't provider a
constant bit rate stream for my device.
So,if I have to write my own  communications driver, where is the best
begining?

Thanks,

Victor

Show quote
"Peter Duniho" <NpOeStPe***@nnowslpianmk.com> дÈëÏûÏ¢
news:op.to99njz18jd0ej@petes-computer.local...
> On Fri, 16 Mar 2007 18:43:18 +0800, Victor <vvhh2002@nospam.nospam> wrote:
>
>> Hi!
>> I need program a constant bitrate rate output for udp such as 5MBps or
>> 4MBps.
>> The .net UDP control couldn't provide any sending speed control function.
>> I have try to do it manually like use asynchronism IO function such as
>> UDPClient.BeginSend(..)..
>> It's not work. the speed that i have setting as 5MBps is actually only be
>> controled between 3MBps~8MBps.
>
> What exactly are you trying to accomplish?
>
> Generally speaking, the best you can do is achieve a target *average*
> speed.  Especially with UDP, but even with TCP (because even if you only
> send one byte at a time, unless you disable Nagle the network stack will
> coalesce your data into larger groups), groups of bytes will be sent out
> at the rated speed of the connection (usually 100Mbps on a LAN, and
> something slower on an Internet connection...128Kbps is common for cable
> modem upload speeds, for example).
>
> It's not really practical to expect a literally constant bitrate data
> transfer for Ethernet (and for a variety of other computer communication
> links for that matter).  You have no control over the low-level hardware
> data transfer rate.  All you can do is monitor both your data transfer
> amount and the clock, and make sure you only send data as fast as your
> target is.  It sounds as though you already are doing this much, so if you
> want something better than that, you are either expecting too much, or you
> need to think about coding your data transfer at a MUCH lower level (that
> is, basically writing your own communications driver...frankly, I doubt
> you really want or need to do this).
>
> If you can be more explicit about why it is you want to have a constant
> bitrate for your data transfer and how you've implemented it so far, it's
> possible you might get a more insightful answer than this one.  Not
> guaranteed, but at least possible.  :)
>
> Pete
Author
17 Mar 2007 9:32 AM
Peter Duniho
On Sat, 17 Mar 2007 10:54:51 +0800, Victor <vvhh2002@nospam.nospam> wrote:

> Thanks, Pete
> I just want program a UDP stream sending application for a IPQAM device 
> that
> is needed by Digial TV VOD Broadcast system.The speed of my server and a
> IPQAM device is 10000Mbps.
> The IPQAM device only can accept a constant bit rate udp TS(mpeg2 
> transport
> stream) data stream for broadcasting TV.

What is the network configuration here?  Does the IPQAM device receive the 
UDP datagrams directly?  What is its relationship to the sender?  Are they 
on the same computer?  On the same LAN?  Or communicating over the 
Internet and/or some other telecommunications link?  Does the sender get 
any feedback whatsoever regarding the state or status of the IPQAM device, 
and/or any other components in the network involved in transmitting the 
data?

What does it mean when you write "only can accept a constant bit rate UDP 
TS data stream"?  I ask, because there is no such thing as a genuinely 
"constant bit rate UDP stream".  UDP isn't stream-oriented in the first 
place, and as a protocol that's part of TCP/IP there's definitely no 
ensuring that the UDP datagrams arrive in an exact frequency (for that 
matter, UDP doesn't guarantee delivery, doesn't guarantee unique delivery, 
and doesn't guarantee in-order delivery).  It seems likely to be that if 
the IPQAM device is actually receiving the UDP datagrams directly, it 
*must* have some sort of buffering.  So you shouldn't really need for the 
transmitted datagrams to be sent at a perfect delivery sequence.  They 
just need to arrive fast enough to keep the IPQAM device's buffer(s) 
filled (or nearly so), without going too fast (causing UDP datagrams to be 
dropped).

If the IPQAM isn't receiving the UDP datagrams directly, then obviously 
there's some other component that is and is passing them along.  That 
other component should be able to do the buffering and even out the flow 
of data to the IPQAM device proper.

Keep in mind that I have no idea what an "IPQAM device" is.  :)  All I 
know is what you've written here, which is that it's some sort of video 
receiver that uses UDP.

As far as your implementation goes, I would offer a few thoughts: one is 
that you probably don't need the high-resolution timer, since network i/o 
is a) not that granular anyway, and b) operates in the realm of 
milliseconds, not microseconds.  The second is that rather than looping, 
it would probably make more sense to just sleep for a given number of 
milliseconds.  This will avoid too much CPU overhead and weird thread 
starvation bugs (which ironically can cause your network i/o to become 
more irregular, even as you are trying to even things out and reduce it).  
Yes, it's true that the Windows thread scheduler does not guarantee that 
you'll be woken up exactly after the time you specify in Sleep(), but as 
long as you are calculating a new wait interval each time (and it appears 
that you are), then you'll be pretty close and will maintain a proper 
average with a minimal of overhead.

It seems to me that if you send an amount of data with each interval that 
is somewhere between 10% and 50% of the IPQAM device's network i/o 
buffers, while at the same time ensuring that you are waiting for some 
reasonable amount of time (ie tens of milliseconds), things ought to work 
reasonably well.  Of course, these two parameters may not be mutually 
compatible, depending on how large the IPQAM device's buffers are.  You 
may have to fiddle with the specifics to get something that works just 
right.

As far as the question of writing your own network driver goes, I don't 
really know.  You'll have to learn all about the low-level definitions of 
UDP and IP (on which UDP is built), as well as the intracacies of driver 
development under Windows (see the Windows DDK).  I think that the network 
driver is a user-mode driver, which should simplify things, but I'm not 
sure about that, and even if it is, you still have the issue of 
interacting with the network hardware driver at a lower level.  Bottom 
line is that it's gonna be complicated if you go that route.  The other 
thing is that even if you develop your own driver, you may not have 
control over the network components between your driver and the IPQAM 
device.  Just because you send data out at a perfectly regulated interval, 
that will not ensure that the data arrives at the device at a perfectly 
regulated interval.  The best-case scenario will be where that device is 
actually on the same computer, and even there the way that i/o happens on 
Windows will prevent you from achieving a perfectly regulated delivery.

And of course, I will reiterate: unless you are sending data one byte at a 
time, the blocks of data you send are still going to be transmitted at the 
nominal rate of the network connection.  If you are sending 1K blocks once 
per second, then that will achieve a 1K/sec data rate, but each 1K block 
is going to be sent at whatever rate the network is (100Mbps, for example).

Since I don't know what an "IPQAM device" is, I cannot comment with much 
authority on its design.  But, assuming it is designed to be even 
minimally aware of TCP/IP networks, there should be no reason at all that 
your data has be sent at *exactly* some rate.  TCP/IP networks just don't 
work that way, and so the designers of the device surely have anticipated 
this and provided for some buffering to allow for somewhat uneven 
delivery.  You should be able to target an average, and as long as you do 
that correctly, things should work fine.

If I were you, I would look more closely at the implementation of the 
average solution first, to see if it can be improved, rather than diving 
into a much more complicated proposal such as writing your own network 
driver.

Pete
Author
19 Mar 2007 7:30 AM
Charles Wang[MSFT]
Hi, Victor,
Since this issue is very technical specific and device related, our
community may not be the best place for supporting such issue. It is
recommended that you contact Microsoft Customer Support Services (CSS) via
telephone so that a dedicated Support Professional can assist you in a more
efficient manner. Please be advised that contacting phone support will be a
charged call.

To obtain the phone numbers for specific technology request please take a
look at the web site listed below.
http://support.microsoft.com/default.aspx?scid=fh;EN-US;PHONENUMBERS

If you are outside the US please see http://support.microsoft.com for
regional support phone numbers.

Appreciate your understanding on this.

Charles Wang
Microsoft Online Community Support
=====================================================
Get notification to my posts through email? Please refer to:
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications

If you are using Outlook Express, please make sure you clear the check box
"Tools/Options/Read: Get 300 headers at a time" to see your reply promptly.


Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
======================================================
When responding to posts, please "Reply to Group" via
your newsreader so that others may learn and benefit
from this issue.
======================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
======================================================

AddThis Social Bookmark Button