How to use C # To Implement UDP packet forwarding

Source: Internet
Author: User

Scenario
If you need to use UDP to transmit large data, such as 10 m images, this breaks through the design principles of UDP. UDP is designed based on "datax", that is, it assumes that each packet you send can be contained in a single package. In addition, the maximum length of UDP data packets is limited by the basic network protocol.

The maximum theoretical length of UDP data packets is 65535 bytes, which contains 8 bytes of data headers and 65527 bytes of data. However, if an IPv4-based network is used for transmission, a 20 bytes IP address packet header is subtracted.
The maximum data length that a single UDP packet can transmit is:

The maximum data length that a single UDP packet can transmit is:

MaxUdpDataLength = 65535-8-20 = 65507 bytes

This requires the packet forwarding and receiving group packet functions of UDP packets.

Subcontracting Function

Copy codeThe Code is as follows: // <summary>
/// UDP packet Splitter
/// </Summary>
Public static class UdpPacketSplitter
{
/// <Summary>
/// Split UDP data packets
/// </Summary>
/// <Param name = "sequence"> serial number of the UDP packet </param>
/// <Param name = "datax"> split UDP packet </param>
/// <Param name = "chunkLength"> length of the split block </param>
/// <Returns>
/// List of separated UDP Packets
/// </Returns>
Public static ICollection <UdpPacket> Split (long sequence, byte [] datax, int chunkLength)
{
If (datasync = null)
Throw new ArgumentNullException ("datasync ");

List <UdpPacket> packets = new List <UdpPacket> ();

Int chunks = datax. Length/chunkLength;
Int remainder = datalist. Length % chunkLength;
Int total = chunks;
If (remainder> 0) total ++;

For (int I = 1; I <= chunks; I ++)
{
Byte [] chunk = new byte [chunkLength];
Buffer. BlockCopy (datasync, (I-1) * chunkLength, chunk, 0, chunkLength );
Packets. Add (new UdpPacket (sequence, total, I, chunk, chunkLength ));
}
If (remainder> 0)
{
Int length = datalist. Length-(chunkLength * chunks );
Byte [] chunk = new byte [length];
Buffer. BlockCopy (datax, chunkLength * chunks, chunk, 0, length );
Packets. Add (new UdpPacket (sequence, total, total, chunk, length ));
}

Return packets;
}
}

Packet forwarding
Copy codeThe Code is as follows: private void WorkThread ()
{
While (IsRunning)
{
Waiter. WaitOne ();
Waiter. Reset ();

While (queue. Count> 0)
{
StreamPacket packet = null;
If (queue. TryDequeue (out packet ))
{
RtpPacket rtpPacket = RtpPacket. FromImage (
RtpPayloadType. JPEG,
Packet. SequenceNumber,
(Long) Epoch. GetDateTimeTotalMillisecondsByYesterday (packet. Timestamp ),
Packet. Frame );

// Max UDP packet length limited to 65,535 bytes
Byte [] datax = rtpPacket. ToArray ();
Packet. Frame. Dispose ();

// Split udp packet to extract packets
// To reduce the size to 65507 limit by underlying IPv4 protocol
ICollection <UdpPacket> udpPackets
= UdpPacketSplitter. Split (
Packet. SequenceNumber,
Datax,
65507-UdpPacket. HeaderSize );
Foreach (var udpPacket in udpPackets)
{
Byte [] udppacketdatasync = udpPacket. ToArray ();
// Async sending
UdpClient. BeginSend (
Udppacketdatasync, udppacketdatasync. Length,
Packet. Destination. Address,
Packet. Destination. Port,
SendCompleted, udpClient );
}
}
}
}
}

Receive group package Function
Copy codeThe Code is as follows: private void onreceivramreceived (object sender, udp;ramreceivedeventargs <byte []> e)
{
Try
{
UdpPacket udpPacket = UdpPacket. FromArray (e. datax );

If (udpPacket. Total = 1)
{
RtpPacket packet = new RtpPacket (udpPacket. Payload, udpPacket. PayloadSize );
Bitmap bitmap = packet. ToBitmap ();
RaiseNewFrameEvent (
Bitmap, Epoch. GetDateTimeByYesterdayTotalMilliseconds (packet. Timestamp ));
}
Else
{
// Rearrange packets to one packet
If (packetCache. ContainsKey (udpPacket. Sequence ))
{
List <UdpPacket> udpPackets = null;
If (packetCache. TryGetValue (udpPacket. Sequence, out udpPackets ))
{
UdpPackets. Add (udpPacket );

If (udpPackets. Count = udpPacket. Total)
{
PacketCache. TryRemove (udpPacket. Sequence, out udpPackets );

UdpPackets = udpPackets. OrderBy (u => u. Order). ToList ();
Int rtpPacketLength = udpPackets. Sum (u => u. PayloadSize );
Int maxPacketLength = udpPackets. Select (u => u. PayloadSize). Max ();

Byte [] rtpPacket = new byte [rtpPacketLength];
Foreach (var item in udpPackets)
{
Buffer. BlockCopy (
Item. Payload, 0, rtpPacket,
(Item. Order-1) * maxPacketLength, item. PayloadSize );
}

RtpPacket packet = new RtpPacket (rtpPacket, rtpPacket. Length );
Bitmap bitmap = packet. ToBitmap ();
RaiseNewFrameEvent (
Bitmap,
Epoch. GetDateTimeByYesterdayTotalMilliseconds (packet. Timestamp ));

PacketCache. Clear ();
}
}
}
Else
{
List <UdpPacket> udpPackets = new List <UdpPacket> ();
UdpPackets. Add (udpPacket );
PacketCache. AddOrUpdate (
UdpPacket. Sequence,
UdpPackets, (k, v) =>{ return udpPackets ;});
}
}
}
Catch (Exception ex)
{
RaiseVideoSourceExceptionEvent (ex. Message );
}
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.