ATTENTION: You are viewing a page formatted for mobile devices; to view the full web page, click HERE.

Other Software > Developer's Corner

Announcing with UDP in C# - Punching above my weight

<< < (2/3) > >>

Stoic Joker:
I don't know where I got these originally (it's not my code), which is unfortunate because I've screwed with them a bit. But this is a UDP client server pair written in C++ that does work that might give you some ideas on how to proceed.

UDP Ping Pong.zip (12.65 kB - downloaded 391 times.)

mediaguycouk:
Thanks Joker

jazper:
I whipped this up real fast, it ain't pretty but should work



--- ---namespace SSDPTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            UdpClient ucs = new UdpClient(12555);

            string data = "M-SEARCH * HTTP/1.1\r\n" +
                            "HOST: 239.255.255.250:1900\r\n" +
                            "ST:upnp:rootdevice\r\n" +
                            "MAN:\"ssdp:discover\"\r\n" +
                            "MX:3\r\n\r\n";
           
            Byte[] sendBytes = Encoding.ASCII.GetBytes(data);
            ucs.Connect("255.255.255.255", 1900);
            ucs.Send(sendBytes, sendBytes.Length);
            ucs.Close();

            IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
            UdpClient ucr = new UdpClient(12555);


            Byte[] receiveBytes = ucr.Receive(ref RemoteIpEndPoint);

            textBox1.Text += Encoding.ASCII.GetString(receiveBytes);

            ucr.Close();

        }
    }
}

mediaguycouk:
Thanks Jazper,
You code confirms what I've previously found. It seems quite easy and reliable to get the router you are connected to to respond to these types of broadcasts but the more unreliable and inconsistent IPTV systems seem to lock up the .Receive commands.

In the end I've been using Wireshark and monitoring the responses of a propriety IPTV multicast program. I then export the filtered Wireshark output into a C# application to get all the channels.


--- Code: C# ---// Please excuse the fact that I found out it was called 'Wireshark' about half way through and then// couldn't be bothered fixing the function namesprivate void btnOpenWireShackFile_Click(object sender, EventArgs e)        {            MessageBox.Show("Remember to select the Wireshark \"K12 Text File\" that you have saved with " +                "the filter 'sap.flags' (no apostrophes) and save \"Packet Range: Displayed\" and \"All packets\"",                "Instructions", MessageBoxButtons.OK, MessageBoxIcon.Information);             btnSave.Enabled = false;             openWireshackTxtFile.Title = "Choose wireshark txt file";            openWireshackTxtFile.Filter = "TXT Files|*.txt";             if (openWireshackTxtFile.ShowDialog(this) == DialogResult.OK)            {                strWireSharkFileLocation = openWireshackTxtFile.FileName;                 replaceBigTextBox("");                replaceM3UTextBox("");                 Thread threadReadHex = new Thread(readHexAndOutputASCII);                threadReadHex.IsBackground = true;                threadReadHex.Start();            }        }         private void readHexAndOutputASCII()        {            if (strWireSharkFileLocation == "VOID")            {                return;            }                        try            {                strWireSharkFile = File.ReadAllLines(strWireSharkFileLocation);            }            catch            {                MessageBox.Show("Failed to open Wireshack file", "Fatal error",                    MessageBoxButtons.OK, MessageBoxIcon.Error);                return;            }             replaceM3UTextBox("#EXTM3U\r\n");             int i = 1;            int j = 0;             foreach (string line in strWireSharkFile)            {                if (line.Length > 2 && line.Substring(0, 2) == "|0")                {                    string[] characters = line.Split('|');                    string completeLine = "";                     foreach (string hex in characters)                    {                                                if (hex.Length == 2)                        {                            try                            {                                int n = Convert.ToInt32(hex, 16);                                if (n >= 32 && n < 255)                                {                                    char c = (char)n;                                    completeLine += c.ToString();                                }                                else if (n == 10)                                {                                    completeLine += "|";                                }                            }                            catch                            {                                // Do we need to do anything here?                            }                        }                    }                     addToBigTextBox(completeLine.Replace("|", "\r\n") + "\r\r\n");                     string[] partLine = completeLine.Split('|');                     foreach (string data in partLine)                    {                         if (data.Length > 3 && data.Substring(0, 2) == "s=")                        {                            string channelName = data.Substring(2, data.Length - 2);                            addToM3UTextBox("#EXTINF:" + i + "," + channelName + "\r\n");                        }                         if (data.Length > 3 && data.Substring(0, 2) == "c=")                        {                            string nospacedata = data.Replace(" ", "");                            string[] splitip = nospacedata.Split('/');                            string ip = splitip[0].Substring(7, splitip[0].Length - 7);                            addToM3UTextBox("udp://" + ip + ":5000" + "\r\n");                        }                                             }                    decimal deProgressBar = (((decimal)j + 1) / (decimal)strWireSharkFile.Length) * 100;                    intProgressBar = (int)Math.Ceiling(deProgressBar);                    changeProgressBar();                    i++;                }                j++;            }            intProgressBar = 100;            changeProgressBar();        }

Stoic Joker:
the more unreliable and inconsistent IPTV systems seem to lock up the .Receive commands.
-mediaguycouk (May 03, 2011, 05:16 AM)
--- End quote ---

Hm... Sorry if I get a little Captain Obvious here, but are you sure the request packet is being replicated exactly? The header may need a bit of tweaking to get the device to respond reliably.

If you put receive in its own thread with a small buffer called in a loop you can then get partial output to display which might help to establish where it's hanging and why.

(Sorry man I got nothing in C#, but...) Here's a Quick-N-Dirty example that I cut out of a project:

--- Code: C++ ---// The thread passes a handle to the edit control to the receive function so tell us what's u.  while(WaitForSingleObject(hStopEvent, 0) != WAIT_OBJECT_0) { // ...When it's Time for it.          if(bPortChange) {                  SetEvent(hStopEvent);          }else{                  Listen4Ping(g_hEdit, s);          }  }  //===========================================================================================//-------------------------------------------------------------+++--> Tell User What You Hear!void Listen4Ping(HWND hEdit, SOCKET soc) { //------------------------------------------+++-->        TCHAR recvbuf[MAX_BUFF] = {0};        TCHAR szTemp[GEN_BUFF] = {0};        SOCKADDR_IN saPong; // IP Address Structure for Local Listener.        int iSenderAddrSize = sizeof(saPong);        int iResult;         timeval tv; // Time Value Object        fd_set fd; // File Descriptor Set   fd.fd_count = 1; //----//-+++--> Number of sockets in the set.  fd.fd_array[0] = soc; // Array of sockets that are in the set.   tv.tv_sec = 1;  // Set Timer Value to Wait Only 1 second...  tv.tv_usec = 0; // With No Additional microseconds to wait.   iResult = select(1, &fd, NULL, NULL, &tv);   if(iResult > 0) {          SOCKET Accpt;          int iBytesRecv;          Accpt = accept(soc,(SOCKADDR *)&saPong, &iSenderAddrSize);          StringCbPrintf(szTemp, GEN_BUFF, "\r\nConnected Client's IP: %s", inet_ntoa(saPong.sin_addr));          SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM)szTemp);          iBytesRecv = recv(Accpt, recvbuf, MAX_BUFF, 0);          SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM)recvbuf);          StringCbPrintf(szTemp, GEN_BUFF, "\r\nBytes Received: %ld\r\n\r\n", iBytesRecv);          SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM)szTemp);          if(Accpt) closesocket(Accpt);  }else{          SendMessage(hEdit, EM_REPLACESEL, FALSE, (LPARAM)".");  }} // Here I get output of something every second regardless of a connection. That was if something does go wrong is obvious even if it isn't bad enough to lock the entire app.

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version