Board index » delphi » Sending a Stream over UDP

Sending a Stream over UDP

I have this strange problem:

I send a stream :

  MemStream := TMemoryStream.Create;
    try
      MemStream.Position := 0;
      MemStream.Write(PFD^, Sizeof(PFD^));
      MemStream.Position := 0;
      IdUDPClient1.SendBuffer(MemStream, MemStream.Size);
    finally
      MemStream.Free;
    end;

I verified the contents of MemStream just before sending , it's ok.

on the UDP server I recieve:

procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
<...>
  DataStream := TMemoryStream.Create;
    try
      DataStream.Position := 0;
      DataStream.CopyFrom(AData, AData.Size);
      DataStream.Position := 0;
      DataStream.SaveToFile('c:\FDC.dmp');
    finally
      DataStream.Free;
    end;

I recieve EXCACTLY the ammount of data send (MemStream.Size = AData.Size)

BUT : the contents is totaly different ??????

I must be doing something totaly wrong, please help.....

using D6/Indy 9.0.11

Erwin Neyt

 

Re:Sending a Stream over UDP


Quote
Erwin Neyt wrote:
> I must be doing something totaly wrong, please help.....

You can't do what you tried:
1) There is a strict limit for the size of data that can bee transferred
via UDP. and this limit is very small.
2) UDP is not reliable protocol, so you are not guaranteed to ever
receive the data.

If you want to deal with messages but want reliability, you need
MsgConnect (see signature). It implements message mode over different
transports including TCP.

--
Eugene Mayevski
Free cross-platform data exchange framework
http://www.msgconnect.com/

Re:Sending a Stream over UDP


Thanks Eugene for your prompt answer.

The issue here is not reliability but speed.

It works well using TCP, but in order to get beter performance I want to try
UDP.

I know of the UDP issues, but was not aware it would not work at all.
You talk of limits, anyone has info about them?

Else I better stuck to TCP.  Is there any info how to get the most out of
TCP?

thanks again,

Erwin.

Quote
"Eugene Mayevski" <mayev...@eldos.org> wrote in message

news:3e7b1383@newsgroups.borland.com...
Quote
> Erwin Neyt wrote:

> > I must be doing something totaly wrong, please help.....

> You can't do what you tried:
> 1) There is a strict limit for the size of data that can bee transferred
> via UDP. and this limit is very small.
> 2) UDP is not reliable protocol, so you are not guaranteed to ever
> receive the data.

> If you want to deal with messages but want reliability, you need
> MsgConnect (see signature). It implements message mode over different
> transports including TCP.

> --
> Eugene Mayevski
> Free cross-platform data exchange framework
> http://www.msgconnect.com/

Re:Sending a Stream over UDP


Quote
Erwin Neyt wrote:
> I know of the UDP issues, but was not aware it would not work at all.
> You talk of limits, anyone has info about them?

Actually, you can look in MSDN. The UDP packet must fit into one
underlying transport frame. As documentation says, 512 bytes will fit.
So the limits are *small*.

Quote

> Else I better stuck to TCP.  Is there any info how to get the most out of
> TCP?

If you need speed and efficiency, do take a look at MsgConnect. It keeps
connection for specified time and when connection is not used, it is
dropped. Then, when you need connection again, it establishes connection
again. And sending a packet with MsgConnect is just a couple of lines of
code.

--
Eugene Mayevski
Free cross-platform data exchange framework
http://www.msgconnect.com/

Re:Sending a Stream over UDP


Quote
>      IdUDPClient1.SendBuffer(MemStream, MemStream.Size);

I don't know the declaration of SendBuffer, but I strongly doubt that
it takes a TMemoryStream as a parameter.

SendBuffer(MemStream.Memory, MemStream.Size)

should be more like it - assuming that the param is pointer.

Quote
>I recieve EXCACTLY the ammount of data send (MemStream.Size = AData.Size)

>BUT : the contents is totaly different ??????

this seconds my suspect - you're sending garbage, you're receiving
garbage

Sending Streams is typically a TCP task though.
Because even if you're doing everything right, UDP doesn't guarantee
anything.
And if you implement error checking etc. for yourself, UDP's speed
advantage is most likely gone with the wind...

Andy

Re:Sending a Stream over UDP


You're right.

This looks much better to me.
   IdUDPClient1.SendBuffer(PFD^, Sizeof(PFD^));

Bas

Quote
"Andy M." <[no-spam]andy.mail...@gmx.net> wrote in message

news:k59m7vs8li134h0t0pj5rrmls34pfpbc5k@4ax.com...
| >      IdUDPClient1.SendBuffer(MemStream, MemStream.Size);
|
| I don't know the declaration of SendBuffer, but I strongly doubt that
| it takes a TMemoryStream as a parameter.
|
| SendBuffer(MemStream.Memory, MemStream.Size)
|
| should be more like it - assuming that the param is pointer.
|
| >I recieve EXCACTLY the ammount of data send (MemStream.Size = AData.Size)
| >
| >BUT : the contents is totaly different ??????
|
| this seconds my suspect - you're sending garbage, you're receiving
| garbage
|
| Sending Streams is typically a TCP task though.
| Because even if you're doing everything right, UDP doesn't guarantee
| anything.
| And if you implement error checking etc. for yourself, UDP's speed
| advantage is most likely gone with the wind...
|
| Andy

Re:Sending a Stream over UDP


I don't really work with IDY components but from looking at your
attempt i would say that your passing the buffer incorrectly.
i can only assume that SendBuffer would expect a memory pointer or object.
you are actually passing a Class Object pointer.
try this.
 SendBuffer(MEmStream.Memory , MemStream.Size);
P.S.
  beware of the packet sizes etc...
Quote
Erwin Neyt wrote:
> I have this strange problem:

> I send a stream :

>   MemStream := TMemoryStream.Create;
>     try
>       MemStream.Position := 0;
>       MemStream.Write(PFD^, Sizeof(PFD^));
>       MemStream.Position := 0;
>       IdUDPClient1.SendBuffer(MemStream, MemStream.Size);
>     finally
>       MemStream.Free;
>     end;

> I verified the contents of MemStream just before sending , it's ok.

> on the UDP server I recieve:

> procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
> ABinding: TIdSocketHandle);
> <...>
>   DataStream := TMemoryStream.Create;
>     try
>       DataStream.Position := 0;
>       DataStream.CopyFrom(AData, AData.Size);
>       DataStream.Position := 0;
>       DataStream.SaveToFile('c:\FDC.dmp');
>     finally
>       DataStream.Free;
>     end;

> I recieve EXCACTLY the ammount of data send (MemStream.Size = AData.Size)

> BUT : the contents is totaly different ??????

> I must be doing something totaly wrong, please help.....

> using D6/Indy 9.0.11

> Erwin Neyt

Re:Sending a Stream over UDP


Lowered the data to 256 bytes and it works.

Erwin

Quote
"Eugene Mayevski" <mayev...@eldos.org> wrote in message

news:3e7b25cd@newsgroups.borland.com...
Quote
> Erwin Neyt wrote:

> > I know of the UDP issues, but was not aware it would not work at all.
> > You talk of limits, anyone has info about them?

> Actually, you can look in MSDN. The UDP packet must fit into one
> underlying transport frame. As documentation says, 512 bytes will fit.
> So the limits are *small*.

> > Else I better stuck to TCP.  Is there any info how to get the most out
of
> > TCP?

> If you need speed and efficiency, do take a look at MsgConnect. It keeps
> connection for specified time and when connection is not used, it is
> dropped. Then, when you need connection again, it establishes connection
> again. And sending a packet with MsgConnect is just a couple of lines of
> code.

> --
> Eugene Mayevski
> Free cross-platform data exchange framework
> http://www.msgconnect.com/

Re:Sending a Stream over UDP


Yup, sending FPD^ directly works, sending a stream not.

BTW MemStream.Memory is not accepted by the compiler.

Erwin.

Quote
"Bas Gooijen" <bas_gooi...@yahoo.com> wrote in message

news:3e7b303a@newsgroups.borland.com...
Quote
> You're right.

> This looks much better to me.
>    IdUDPClient1.SendBuffer(PFD^, Sizeof(PFD^));

> Bas

> "Andy M." <[no-spam]andy.mail...@gmx.net> wrote in message
> news:k59m7vs8li134h0t0pj5rrmls34pfpbc5k@4ax.com...
> | >      IdUDPClient1.SendBuffer(MemStream, MemStream.Size);
> |
> | I don't know the declaration of SendBuffer, but I strongly doubt that
> | it takes a TMemoryStream as a parameter.
> |
> | SendBuffer(MemStream.Memory, MemStream.Size)
> |
> | should be more like it - assuming that the param is pointer.
> |
> | >I recieve EXCACTLY the ammount of data send (MemStream.Size =
AData.Size)
> | >
> | >BUT : the contents is totaly different ??????
> |
> | this seconds my suspect - you're sending garbage, you're receiving
> | garbage
> |
> | Sending Streams is typically a TCP task though.
> | Because even if you're doing everything right, UDP doesn't guarantee
> | anything.
> | And if you implement error checking etc. for yourself, UDP's speed
> | advantage is most likely gone with the wind...
> |
> | Andy

Re:Sending a Stream over UDP


Quote
Erwin Neyt wrote:
> Yup, sending FPD^ directly works, sending a stream not.
> BTW MemStream.Memory is not accepted by the compiler.

You can't pass the property as var parameter, but maybe you can do this:

SendBuffer(PChar(MemStream.Memory)^, MemStream.Size)

--
Eugene Mayevski
Free cross-platform data exchange framework
http://www.msgconnect.com/

Re:Sending a Stream over UDP


That's not true.  A UDP packet must fit inside a physical layer frame to
*only* avoid fragmentation.  This limit is known as the MTU.  Over dialup
links something in the order of 576 bytes is usual, on Ethernet it's 1514
bytes other physical implementation such as Token Ring, ATM or FDDI have
differing limits still.

The maximum packet size is 64k (including the minimum 28 bytes for the IP
and UDP header) as dictated by the 16 bit total length field in the IP
header but sending a packet larger than the MTU will result in automatic
fragmentation by the OS.

Fragmentation is usually handled by end systems and is not something that
you need to worry about.  Obviously if you write your protocol in such a
manner that all the packets *do* fit into a physical frame then the
recepient OS will never have to recombine the fragments so there will be a
*small* benefit here.  It's worth pointing out too that fragmentation
naturally occurs across the internet anyway (at points where the physical
medium changes from one type to another) and is handled by the intermediary
routers.

TCP has the same maximum packet size limitations because it to is subject to
the 16 bit IP total length field.  Packets larger than the MTU are also
fragmented because the fragmentation is handled by the network (IP) layer
rather than the transport (UDP/TCP) layer.

This is a bit long winded but I hope it clears things up a little.

Quote
"Eugene Mayevski" <mayev...@eldos.org> wrote in message

news:3e7b25cd@newsgroups.borland.com...
Quote
> Erwin Neyt wrote:

> > I know of the UDP issues, but was not aware it would not work at all.
> > You talk of limits, anyone has info about them?

> Actually, you can look in MSDN. The UDP packet must fit into one
> underlying transport frame. As documentation says, 512 bytes will fit.
> So the limits are *small*.

Re:Sending a Stream over UDP


Quote
Simon Devlin wrote:
> The maximum packet size is 64k (including the minimum 28 bytes for the IP
> and UDP header) as dictated by the 16 bit total length field in the IP
> header but sending a packet larger than the MTU will result in automatic
> fragmentation by the OS.

Thank you for detailed explanation! One thing to keep in mind is that
you will not be able to send over 64K anyway. Also, I don't know how to
explain this, but we did have problems with UDP packets of size over 1K
on Palm devices.

--
Eugene Mayevski
Free cross-platform data exchange framework
http://www.msgconnect.com/

Re:Sending a Stream over UDP


Never tried anything IP related on a Palm or other handheld, so I'll file
that away for future reference.

Thanks

Quote
"Eugene Mayevski" <mayev...@eldos.org> wrote in message

news:3e7b77a0@newsgroups.borland.com...
Quote

> Thank you for detailed explanation! One thing to keep in mind is that
> you will not be able to send over 64K anyway. Also, I don't know how to
> explain this, but we did have problems with UDP packets of size over 1K
> on Palm devices.

Re:Sending a Stream over UDP


I believe this is incorrect.

UDP packets can be up to 64K.  Unlike TCP, A UDP packet will not be
fragmented.  It will be dropped if a router in its path can not handle it.
Keeping the packet size below the lowest MTU threshold will allow the packet
to go through unimpeded.    TCP/IP will fragment and recombine packets in
order to fullfill the MTU requirement.

MTU can be optimized given the underlying protocol.  I adjusted MTU to 512
for a wireless network and back up to 1498 for my DSL network.  I've heard
of it being adjusted to 64 and 256 bytes over lowsy networks in an effort to
reduce retransmissions.

Charles

Quote
"Simon Devlin" <simon.dev...@kremlin-computing.com> wrote in message

news:3e7b7459@newsgroups.borland.com...
Quote
> That's not true.  A UDP packet must fit inside a physical layer frame to
> *only* avoid fragmentation.  This limit is known as the MTU.  Over dialup
> links something in the order of 576 bytes is usual, on Ethernet it's 1514
> bytes other physical implementation such as Token Ring, ATM or FDDI have
> differing limits still.

> The maximum packet size is 64k (including the minimum 28 bytes for the IP
> and UDP header) as dictated by the 16 bit total length field in the IP
> header but sending a packet larger than the MTU will result in automatic
> fragmentation by the OS.

> Fragmentation is usually handled by end systems and is not something that
> you need to worry about.  Obviously if you write your protocol in such a
> manner that all the packets *do* fit into a physical frame then the
> recepient OS will never have to recombine the fragments so there will be a
> *small* benefit here.  It's worth pointing out too that fragmentation
> naturally occurs across the internet anyway (at points where the physical
> medium changes from one type to another) and is handled by the
intermediary
> routers.

> TCP has the same maximum packet size limitations because it to is subject
to
> the 16 bit IP total length field.  Packets larger than the MTU are also
> fragmented because the fragmentation is handled by the network (IP) layer
> rather than the transport (UDP/TCP) layer.

> This is a bit long winded but I hope it clears things up a little.

> "Eugene Mayevski" <mayev...@eldos.org> wrote in message
> news:3e7b25cd@newsgroups.borland.com...
> > Erwin Neyt wrote:

> > > I know of the UDP issues, but was not aware it would not work at all.
> > > You talk of limits, anyone has info about them?

> > Actually, you can look in MSDN. The UDP packet must fit into one
> > underlying transport frame. As documentation says, 512 bytes will fit.
> > So the limits are *small*.

Re:Sending a Stream over UDP


Quote
"Simon Devlin" <simon.dev...@kremlin-computing.com> wrote in message

news:3e7d4c54@newsgroups.borland.com...

Quote

> 17:40:44.474613 192.168.0.254.20059 > 239.3.250.1.8000:  udp 3366 (frag
> 48277:1480@0+) (ttl 7, len 1500)
> 17:40:44.474720 192.168.0.254 > 239.3.250.1: (frag 48277:1480@1480+) (ttl
7,
> len 1500)
> 17:40:44.474756 192.168.0.254 > 239.3.250.1: (frag 48277:414@2960) (ttl 7,
> len 434)
> 17:40:44.492460 192.168.0.254.20059 > 239.3.250.1.8000:  udp 67 (ttl 7, id
> 48278, len 95)

Please take into account the wrapping on the lines above.
Go to page: [1] [2]

Other Threads