Solved

Message sender via UDP

Posted on 2016-09-01
19
27 Views
Last Modified: 2016-09-21
Hello
maybe i can have some help...

i have a small windows form that i want to use to do 3 things

1) send via UDP 4 lines of message form 4 textboxes (TBline1-4)  to a specific IP address specific in a textbox (TBIP).
2) "broadcast" to all connected devices the message(s) in each of the Textboxes (TBLine1-4)
3) send a PING to ALL devices connected in the same network

finally, those messages need to be changed to ASCII before sending...

here is my code, i can't make it work...
    Dim publisher As New Sockets.UdpClient(0)
    Dim listener As New Sockets.UdpClient(3100)
    Dim RemEP As IPEndPoint ' Dim RemEP As New IPEndPoint(IPAddress.Parse((TBIP.Text)), 3100) 'Dim RemEP As New IPEndPoint(IPAddress.Parse("192.168.199.253"), 3100) 
    Dim RemALL As New IPEndPoint(IPAddress.Any, 3100)

    '** ONE DISPLAY
    Private Sub BtDis_Click(sender As Object, e As EventArgs) Handles BtDis.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Dim rcvbytes() As Byte
        Dim RemEP As IPEndPoint
        Static pageNumber As Integer = 1

        RemEP = New IPEndPoint(TBIP.Text, 3100)

        Try
            TempString = ""
            TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text
            TempString &= Chr(2) & TempString & Chr(3)
            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
            sendbytes = ASCII.GetBytes(TempString)

            listener.Send(sendbytes, sendbytes.Length, RemEP)

            Try
                If listener.Available Then
                    rcvbytes = listener.Receive(RemEP)

                End If
            Catch ex As Exception
            End Try
        Catch ex As Exception
        End Try
    End Sub

    '** SEND TO ALL
    Private Sub BtAll_Click(sender As Object, e As EventArgs) Handles BtAll.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Static pageNumber As Integer = 1
        Dim RemALL As New IPEndPoint(IPAddress.Any, 3100)

        Try
            TempString = ""
            TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text
            TempString &= Chr(2) & TempString & Chr(3)

            'TempString &= Chr(2) & TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text & Chr(3) ' STX & string & ETX //TempString = Chr(2) & TempString & Chr(3) 
            'TempString &= "$"
            'TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text
            'TempString &= Chr(2) & TempString & Chr(3)
            'TempString &= TBLine1.Text & vbCr & TBLine2.Text & vbCr & TBLine3.Text & vbCr & TBLine4.Text
            'TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text

            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
            sendbytes = ASCII.GetBytes(TempString)
            listener.Send(sendbytes, sendbytes.Length, RemALL)
        Catch ex As Exception
        End Try

    End Sub

    '**PING
    Private Sub BtPing_Click(sender As Object, e As EventArgs) Handles BtPing.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Static pageNumber As Integer = 1

        RemEP = New IPEndPoint((TBIP.Text), 3100)

        TBPing.Clear()
        Try
            TempString = ""
            TempString &= "PING"
            TempString &= TempString & vbCr 'TempString &= Chr(2) & TempString & Chr(3)

            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
            sendbytes = ASCII.GetBytes(TempString)
            listener.Send(sendbytes, sendbytes.Length, RemEP)
        Catch ex As Exception
        End Try

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Clear()
        listener.Client.ReceiveTimeout = 100
        listener.Client.Blocking = False
    End Sub

    Private Sub Form1_Close(sender As Object, e As EventArgs) Handles MyBase.Closed
        '       listener.Close()
        'listener.Client.Blocking = True
    End Sub


    'TIMER FOR RESPONSE
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Try
            Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 3100)
            Dim rcvbytes() As Byte
            If listener.Available Then
                rcvbytes = listener.Receive(ep)
                TextBox20.Text = ASCII.GetString(rcvbytes)
            End If
        Catch ex As Exception
        End Try
    End Sub

    Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click
        TBIP.Clear()
        TBLine1.Clear()
        TBLine2.Clear()
        TBLine3.Clear()
        TBLine4.Clear()
        TBPing.Clear()
        ' TextBox20.Clear()
    End Sub

    Public Sub Clear()
        TBIP.Clear()
        TBLine1.Clear()
        TBLine2.Clear()
        TBLine3.Clear()
        TBLine4.Clear()
        TBPing.Clear()
        TextBox20.Clear()
    End Sub

Open in new window

0
Comment
Question by:Henry Ottiz
  • 9
  • 9
19 Comments
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41781574
Your code has many different parts to it.  Can you be a BIT more specific than "it doesn't work"?  
- Is it doing ANYTHING?
- Is it returning a compiler error? If so, what error?
- Is it returning a runtime error?  If so, what error?
- How are you sure that it is not working?  UDP is a connectionless protocol, so there is no guarantee of delivery in the first place.  Are you using a tool like Wireshark to see the packet leave the workstation?

Please add a bit more clarity to the question.  Most of us don't mind helping (that's why we are here), but spending time to build a test environment just to try to compile and run your code is a bit out of the norm.

Another good troubleshooting tool is to add some debugging MsgBox calls to the code.  This can tell you exactly where in the code it is any any point, and you can display critical variable values at that point (IP address, message text, etc.).  It will help verify that the data values are what you THINK they are.
0
 

Author Comment

by:Henry Ottiz
ID: 41781670
than kyou for your response, details below

Your code has many different parts to it.  Can you be a BIT more specific than "it doesn't work"?  
- Is it doing ANYTHING?
>> it is supposed to communicate, if you put a fixed IP (parse...) it does, but that is not the intention. on the first part it has to use the specified IP on the TBIP textbox, but when doing so, the ENDPOINT is not working and throwing the following error (code included)

this is the new IPendpoint
  Dim RemEP As New IPEndPoint(IPAddress.Parse(TBIP.Text), 3100)

it does not like it, not sure why, the error is:

An exception of type 'System.NullReferenceException' occurred in SPSS_DIS404.exe but was not handled in user code

it also happens when i try and use the IPaddress.any, when i try to send to all connected devices.

thank you.

PS: the code is separated in 3 sections

- send to 1 device /display
- send to all devices
- send a ping to check how many devices are connected...
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41781825
OK.  Let's work it one thing at a time.  First, you corrected the DIM line in this latest post -- but the DIM you are referring to seems to be a global variable!  There is a different DIM for RemEP inside the BtDis_Click function.  I think you need to be changing the local definition instead.  (This is a common issue that arises when you use global variables and locals with the same name.)

Second, the code fragment doesn't indicate the data type of TBIP.Text, but the Parse function needs a String to be sure.  Since you already have tempstring defined, try putting this inside Sub BtDis_Click:
    tempstring = TBIP.Text
    MsgBox "TempString is <" & tempstring & ">"
    RemEP = New IPEndPoint(IPAddress.Parse(TBIP.Text), 3100)

If you have added more MsgBox functions, you might want to post your latest code, too, as that will help determine that all is working as expected...
0
 

Author Comment

by:Henry Ottiz
ID: 41781847
hello, Bill,
no additions to the code (message boxes)...

Let me see if I understand, (code below) as yo mention 1 step at a time.

for 1 Ddisplay only, the code should look like this?

    Private Sub BtDis_Click(sender As Object, e As EventArgs) Handles BtDis.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Dim rcvbytes() As Byte
        Dim RemEP As IPEndPoint
        Static pageNumber As Integer = 1


        'SETUP TO SEND ONLY TO 1 DISPLAY: TBIP.Text
        Try
            TempString = TBIP.Text
            MsgBox("TempString is <" & TempString & ">")
            RemEP = New IPEndPoint(IPAddress.Parse(TBIP.Text), 3100)

            TempString = ""
            TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text
            TempString &= Chr(2) & TempString & Chr(3)
            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
            sendbytes = ASCII.GetBytes(TempString)

            Try
                If listener.Available Then
                    rcvbytes = listener.Receive(RemEP)
                End If
            Catch ex As Exception
            End Try
        Catch ex As Exception
        End Try
    End Sub
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41781857
Sorry for the confusion -- cut&paste error:

        Try
            TempString = TBIP.Text
            MsgBox("TempString is <" & TempString & ">")
            RemEP = New IPEndPoint(IPAddress.Parse(Tempstring), 3100)
0
 

Author Comment

by:Henry Ottiz
ID: 41781889
thanks for your help, but i am not following...

my doubt is that I am not trying to send the TBIP.Text,  I am trying to use that TBIP.Text as my specific IP in :
RemEP = New IPEndPoint(IPAddress.Parse(TBIP.Text), 3100)

my TempString is the combination of the other textboxes (TBLin1-4):
TempString = ""
TempString &= TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text
TempString &= Chr(2) & TempString & Chr(3)

that, in theory, (once the connection can be established), will convert to ASCII and send it to the specific device/IP in TBIP.text...
0
 
LVL 28

Accepted Solution

by:
Bill Bach earned 500 total points (awarded by participants)
ID: 41781929
I understand.  However, you are telling me that the runtime error comes in when you attempt to run this line:
    RemEP = New IPEndPoint(IPAddress.Parse(TBIP.Text), 3100)

So, clearly, this line is your issue. My postulation was that the "TBIP.Text" field could not be directly translated into a String field, and was therefore causing the problem when you send it to the Parse function.  My solution was to use the existing string called TempString, which would force the TBIP.Text field into a String data element FIRST, then display the actual contents of that string element (as validation), and THEN make the call to IPAddress.Parse (and then IPEndPoint).

If you don't wish to re-use the existing TempString variable, that's fine.  In that case, create a new string variable and use it instead:
    DIM TempIPText AS String
    TempIPText = TBIP.Text
    MsgBox("TempIPText is <" & TempIPText & ">")
    RemEP = New IPEndPoint(IPAddress.Parse(TempIPText), 3100)
0
 

Author Comment

by:Henry Ottiz
ID: 41781958
thanks!
ok, I see the message box on display that the IP is what I put in the TBIP.Text

Next:
 still no transmission to the specified display...

i entered the text on the TBLInes1-4 but nothing
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41781965
Did that fix the Null Pointer Exception, at least?
1
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 28

Expert Comment

by:Bill Bach
ID: 41781974
Also, in your last code (ID: 41781847) post, this line seems to have been removed:
    listener.Send(sendbytes, sendbytes.Length, RemEP)
0
 

Author Comment

by:Henry Ottiz
ID: 41781985
it works!!
thanks! for some reason i deleted that line!

ok i will do the rest of programming for the other two buttons and upload the fuinal code,

thanks so much!!!
0
 

Author Comment

by:Henry Ottiz
ID: 41782094
since we are on a roll, two questions that just came to mind

1) to confirm if this code is correct. once i send the PING command, i should receive a response from all devices, how do i separate each response by IP and display it with time and IP
ry
            Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 3100)
            Dim rcvbytes() As Byte
            If listener.Available Then
                rcvbytes = listener.Receive(ep)
                TextBox20.AppendText("Time: " & Now & "/" & Now.Millisecond & "- IP:" & rcvbytes.ToString & vbNewLine)

            End If
        Catch ex As Exception
        End Try

2) how can i display the response sent from the display in ASCII (no conversion) on a separate Textbox?
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41782144
1) Yeah -- you got me on THAT one.  ;-)

Remember that UDP transmissions do not allow for guaranteed delivery.  Even if you send a packet, it may not arrive.  Even if it arrives and they send back a reply, it may not make it back. This is especially the case if there are firewalls involved (like with Windows 7).  Also, I wonder what will happen if you suddenly receive back 100 different replies but are unable to process them all quickly enough -- will the OS queue them up for you?  Or will it decide that UDP is non-critical and simply discard the extra packets?

What I believe you should do is to spawn a completely separate thread to handle the listening. If you don't want to do this, then you might be able to enter into a loop for a set period of time (say, 3 seconds).  While you're in this loop, receive any packets that come in and handle them accordingly. At the end of three seconds, assuming no more packets are waiting to be handled, terminate the loop.

I did a quick lookup, and found this page: https://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.receive(v=vs.110).aspx
Note that the Receive method is a blocking method, and it will halt the thread until a data packet is available.  I assume that "listener.Available" will check to see if a packet is ready to be received?  If so, then you can use this in your loop, too, and make sure to NOT call Receive unless a packet is waiting, to avoid halting your code.

This all reminds me of a project I once implemented on an AT&T StarLAN network in the late 80's to synchronize time between client PCs and a server.  The client sent a NetBIOS broadcast message to request the time and then posted a listener for a reply.  The Server had already posted a listener process, and when it saw a request come in, it broadcast back out the current time, which was then picked up by the client. (If the reply was missed, the odds were that another client would issue another request shortly, and that one would hopefully be seen.)  Of course, back then, it was all done in 8086 assembler code, and the first time I ran it, a bug in the server-side caused the server to reboot itself.  Oops!  Anyway, I digress......

2) Not sure I understand this question, but I'll take a guess: I assume that if you have a textbox already built, you can simply append the contents of the incoming packet to that text box contents and refresh it onscreen.
0
 

Author Comment

by:Henry Ottiz
ID: 41782167
thanks I will check this//
 to keep it simple, going back to the responses..
>> how would i display ANY response on 1 of the 2 textboxes, i Undestand on the UDP protocol loosing packages...
>> the other textbox would be the response in ASCII not conveted through the "ASCII command..."
>> if I wanted to change to TCP, would it make it more reliable?

as promised,  here is the code (without the response part that is pending, i will post that section when i get it)

you have been tremendous help!!

  Dim publisher As New Sockets.UdpClient(0)
    Dim listener As New Sockets.UdpClient(3100)


    '** ONE DISPLAY
    Private Sub BtDis_Click(sender As Object, e As EventArgs) Handles BtDis.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Dim TempIPText As String
        Dim rcvbytes() As Byte
        Dim RemEP As IPEndPoint
        Static pageNumber As Integer = 1


        'SETUP TO SEND ONLY TO 1 DISPLAY: TBIP.Text
        Try
            If TBIP.Text = String.Empty Then
                MsgBox("A DISPLAY IP # MUST BE ENTERED", MsgBoxStyle.Critical)

            Else
                TempIPText = TBIP.Text
                RemEP = New IPEndPoint(IPAddress.Parse(TempIPText), 3100)

                TempString = ""
                TempString &= vbCr & Chr(2) & TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text & Chr(3) & vbCr ' TempString &= Chr(2) & TempString & Chr(3)

                If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
                sendbytes = ASCII.GetBytes(TempString)
                listener.Send(sendbytes, sendbytes.Length, RemEP)
                Try
                    If listener.Available Then
                        rcvbytes = listener.Receive(RemEP)
                    End If
                Catch ex As Exception
                End Try
            End If
        Catch ex As Exception
        End Try
    End Sub

    '** 'SEND TO ALL DISPLAYS - BROADCAST
    Private Sub BtAll_Click(sender As Object, e As EventArgs) Handles BtAll.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Dim rcvbytes() As Byte
        Dim RemEP As IPEndPoint
        Static pageNumber As Integer = 1

        Try
            RemEP = New IPEndPoint(IPAddress.Broadcast, 3100)

            TempString = ""
            TempString &= vbCr & Chr(2) & TBLine1.Text & "^40" & TBLine2.Text & "^80" & TBLine3.Text & "^120" & TBLine4.Text & Chr(3) & vbCr ' TempString &= Chr(2) & TempString & Chr(3)

            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
            sendbytes = ASCII.GetBytes(TempString)
            listener.Send(sendbytes, sendbytes.Length, RemEP)
            Try
                If listener.Available Then
                    rcvbytes = listener.Receive(RemEP)
                End If
            Catch ex As Exception
            End Try
        Catch ex As Exception
        End Try
    End Sub

    '**'SEND PING TO ALL 
    Private Sub BtPing_Click(sender As Object, e As EventArgs) Handles BtPing.Click
        Dim sendbytes() As Byte
        Dim TempString As String
        Dim rcvbytes() As Byte
        Dim RemEP As IPEndPoint
        Static pageNumber As Integer = 1

        Try
            RemEP = New IPEndPoint(IPAddress.Broadcast, 3100)

            TempString = ""
            TempString &= vbCr & Chr(2) & "PING" & Chr(3) & vbCr

            If pageNumber < 255 Then pageNumber += 1 Else pageNumber = 1
                sendbytes = ASCII.GetBytes(TempString)
                listener.Send(sendbytes, sendbytes.Length, RemEP)
                Try
                    If listener.Available Then
                        rcvbytes = listener.Receive(RemEP)
                    End If
                Catch ex As Exception
                End Try

        Catch ex As Exception
        End Try

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'Clear()
        listener.Client.ReceiveTimeout = 100
        listener.Client.Blocking = False
    End Sub
End Class 

Open in new window

0
 

Author Comment

by:Henry Ottiz
ID: 41782183
how about this?
i was thinking on putting in a timer routine...
 Dim ep As New IPEndPoint(IPAddress.Any, 0)
        Dim receivingUdpClient As New UdpClient(3100)

        Try
            Dim rcvbytes() As Byte = receivingUdpClient.Receive(ep)
            If listener.Available Then
               
                Dim response As String = Encoding.ASCII.GetString(rcvbytes)
                TextBox20.AppendText("Time: " & Now & "/" & "- IP:" & ep.Address.ToString() & "message" & rcvbytes.ToString & vbNewLine)
              
            End If
        Catch ex As Exception
        End Try

Open in new window

0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41782201
That looks like it would work.  TCP would certainly be more reliable, but you have to set up and tear down the connections, so it is more work and slower, too.  Ultimately, it is just a question of whether you MUST have the replies, or if this is just a "nice thing".
0
 

Author Comment

by:Henry Ottiz
ID: 41782214
thanks bill!
i will test it and if it works will upload the final code all together...
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 41808388
This answer resolved the initial problems with the code.
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Article by: Ahmedn1
Introduction Some developers today tend to use Skypekit in their applications to make it more interactive with the user. Skype API is very awesome indeed but the problem is it is only available in C++, Java and Python. I can't understand why Micr…
This is the first one of a series of articles I’ll be writing to address technical issues that are always referred to as network problems. The network boundaries have changed, therefore having an understanding of how each piece in the network  puzzl…
The goal of the tutorial is to teach the user how to instant message and make a video call in Skype.
After creating this article (http://www.experts-exchange.com/articles/23699/Setup-Mikrotik-routers-with-OSPF.html), I decided to make a video (no audio) to show you how to configure the routers and run some trace routes and pings between the 7 sites…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now