locked
Sending data on UDP connection

    Question

  • Hi!
    Now that I've established a UDP P2P (peer-to-peer) connection with the remote device, I have to send data.

    On a TCP connection (stream) I read the bytes of the file to send and send them on the stream.  The fact that when looking at the sniffer, I see that the data is broken into packets doesn't interest me - it gets successfully to the device.

    TCP:
    NetworkStream stream = tcpClient.GetStream();
    if (stream.CanWrite)
    {
        stream.Write(sendMsg, 0, sendLen);
        PutMessageOnForm("TCP: sent param len = " + sendLen);
    }
    stream.Close();

    Using UDP, I tried something similar, and I got an error when I looked at the sniffer file that the data length is too big for a packet.  I guess I assumed that C# implementation of UDP would "know" how to break the data into packets.

    UDP:
    udpClient = new UdpClient(udpLocalPort);
    udpClient.Send(sendMsg, sendLen, UDPremote);
    PutMessageOnForm("UDP: sent param len = " + sendLen + " to " +
                                UDPremote.Address.ToString() +" on port " + UDPremote.Port.ToString());
    udpClient.Close();

    I'd appreciate any ideas about what the correct packet lengths should be and if C# can do it for me or do I have to break the data up manually.
    Thanks!
    Mechi

    Mechi
    Tuesday, July 22, 2008 11:08 AM

Answers

  • Mr. Blum gives us a great example of UDP communications:

    /*
    C# Network Programming 

    by Richard Blum

    Publisher: Sybex 
    ISBN: 0782141765
    */
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;

    public class BestUdpClient
    {
       private static byte[] data = new byte[1024];
       private static IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
       private static EndPoint Remote = (EndPoint)sender;
       private static int size = 30;

       private static int AdvSndRcvData(Socket s, byte[] message, EndPoint rmtdevice)
       {
          int recv = 0;
          int retry = 0;

          while (true)
          {
             Console.WriteLine("Attempt #{0}", retry);
             try
             {
                s.SendTo(message, message.Length, SocketFlags.None, rmtdevice);
                data = new byte[size];
                recv = s.ReceiveFrom(data, ref Remote);
             catch (SocketException e)
             {
                if (e.ErrorCode == 10054)
                   recv = 0;
                else if (e.ErrorCode == 10040)
                {
                   Console.WriteLine("Error receiving packet");
                   size += 10;
                   recv = 0;
                }
             }

             if (recv > 0)
             {
                return recv;
             else
             {
                retry++;
                if (retry > 4)
                {
                   return 0;
                }
             }
          }
       }

       public static void Main()
       {
          string input, stringData;
          int recv;
          IPEndPoint ipep = new IPEndPoint(
                          IPAddress.Parse("127.0.0.1")9050);

          Socket server = new Socket(AddressFamily.InterNetwork,
                         SocketType.Dgram, ProtocolType.Udp);

          int sockopt = (int)server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
          Console.WriteLine("Default timeout: {0}", sockopt);
          server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
          sockopt = (int)server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
          Console.WriteLine("New timeout: {0}", sockopt);
     
          string welcome = "Hello, are you there?";
          data = Encoding.ASCII.GetBytes(welcome);

          recv = AdvSndRcvData(server, data, ipep);
          if (recv > 0)
          {
             stringData = Encoding.ASCII.GetString(data, 0, recv);
             Console.WriteLine(stringData);
          else
          {
             Console.WriteLine("Unable to communicate with remote host");
             return;
          }

          while(true)
          {
             input = Console.ReadLine();
             if (input == "exit")
                break;
             recv = AdvSndRcvData(server, Encoding.ASCII.GetBytes(input), ipep);
             if (recv > 0)
             {
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                Console.WriteLine(stringData);
             else
                Console.WriteLine("Did not receive an answer");
          }
          Console.WriteLine("Stopping client");
          server.Close();
       }
    }

        

    Javaman
    • Marked as answer by MechiF Sunday, July 27, 2008 1:46 PM
    Tuesday, July 22, 2008 11:44 AM

All replies

  • Mr. Blum gives us a great example of UDP communications:

    /*
    C# Network Programming 

    by Richard Blum

    Publisher: Sybex 
    ISBN: 0782141765
    */
    using System;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;

    public class BestUdpClient
    {
       private static byte[] data = new byte[1024];
       private static IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
       private static EndPoint Remote = (EndPoint)sender;
       private static int size = 30;

       private static int AdvSndRcvData(Socket s, byte[] message, EndPoint rmtdevice)
       {
          int recv = 0;
          int retry = 0;

          while (true)
          {
             Console.WriteLine("Attempt #{0}", retry);
             try
             {
                s.SendTo(message, message.Length, SocketFlags.None, rmtdevice);
                data = new byte[size];
                recv = s.ReceiveFrom(data, ref Remote);
             catch (SocketException e)
             {
                if (e.ErrorCode == 10054)
                   recv = 0;
                else if (e.ErrorCode == 10040)
                {
                   Console.WriteLine("Error receiving packet");
                   size += 10;
                   recv = 0;
                }
             }

             if (recv > 0)
             {
                return recv;
             else
             {
                retry++;
                if (retry > 4)
                {
                   return 0;
                }
             }
          }
       }

       public static void Main()
       {
          string input, stringData;
          int recv;
          IPEndPoint ipep = new IPEndPoint(
                          IPAddress.Parse("127.0.0.1")9050);

          Socket server = new Socket(AddressFamily.InterNetwork,
                         SocketType.Dgram, ProtocolType.Udp);

          int sockopt = (int)server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
          Console.WriteLine("Default timeout: {0}", sockopt);
          server.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 3000);
          sockopt = (int)server.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout);
          Console.WriteLine("New timeout: {0}", sockopt);
     
          string welcome = "Hello, are you there?";
          data = Encoding.ASCII.GetBytes(welcome);

          recv = AdvSndRcvData(server, data, ipep);
          if (recv > 0)
          {
             stringData = Encoding.ASCII.GetString(data, 0, recv);
             Console.WriteLine(stringData);
          else
          {
             Console.WriteLine("Unable to communicate with remote host");
             return;
          }

          while(true)
          {
             input = Console.ReadLine();
             if (input == "exit")
                break;
             recv = AdvSndRcvData(server, Encoding.ASCII.GetBytes(input), ipep);
             if (recv > 0)
             {
                stringData = Encoding.ASCII.GetString(data, 0, recv);
                Console.WriteLine(stringData);
             else
                Console.WriteLine("Did not receive an answer");
          }
          Console.WriteLine("Stopping client");
          server.Close();
       }
    }

        

    Javaman
    • Marked as answer by MechiF Sunday, July 27, 2008 1:46 PM
    Tuesday, July 22, 2008 11:44 AM
  • Thanks!
    I've seen this - I didn't really want to go down tot he socket level - but I guess i have no choice!
    Mechi
    Mechi
    Sunday, July 27, 2008 1:46 PM