[VB.NET] Sturen van UDP-berichtje in Timer-Functie

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
Graag zou ik een simpel/kort berichtje willen sturen middels UDP.

Ik gebruik daarvoor de volgende code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
  Private Sub Button66_Click(sender As Object, e As EventArgs) Handles Button66.Click

        Try

            receivingUdpClient.Connect(tbIPSendUDP.Text, tbIPPortUDP.Text)
            Dim bytCommand = Encoding.ASCII.GetBytes(tbTextSendUDP.Text)
            receivingUdpClient.Send(bytCommand, bytCommand.Length)

        Catch ex As Exception
            MsgBox("Fout bij Send(" & tbTextSendUDP.Text & "). Melding: " & ex.Message)
        End Try

    End Sub


Als ik op de button druk wordt het berichtje netjes verstuurd.
Alles werkt zo ver :D

Totdat ik dit wil "automatiseren" met een simpele Timer...

code:
1
2
3
4
5
   Private Sub tmrBattery_Tick(sender As Object, e As EventArgs) Handles tmrBattery.Tick
       
        Button66_Click(sender, e)

    End Sub



Het UDP berichtje komt dan NIET aan bij de ontvanger.
Ik heb het idee dat het wél verstuurd wordt, want tijdens dubeggen zie ik geen foutmeldingen...

Hoe kan het nu dat het "handmatig" wel gewoon lukt, en met een Timer niet?

Alle voorbeelden over hoe met UDP te versturen (en eventueel ontvangen) werken natuurlijk met een button voor de eenvoud.
Er is niets te vinden dat iemand het met een Timer doet helaas.

Wat zou hier het probleem kunnen zijn? En minstens even belangrijk: hoe los ik dit op? _/-\o_

Beste antwoord (via Atmoz op 08-05-2022 18:17)


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Atmoz schreef op dinsdag 19 oktober 2021 @ 12:43:
[...]
Nee, dat werkt helaas niet...
(niet met de UDP-send-code van hierboven)
Dan moet je wat meer debuggen, want ik vermoed dat je nog steeds gewoon een cross-thread exception krijgt, en dus iets niet goed doet.

Dus als ik jou was zou ik eens gaan debuggen, een breakpoint op regel 10 van de gepost code zal waarschijnlijk opheldering geven.

Als je iets van een function maakt
C#:
1
2
3
4
5
6
public void SendUdpMessage(string ip, string port, string text)
{
    receivingUdpClient.Connect(ip, port)
    Dim bytCommand = Encoding.ASCII.GetBytes(text)
    receivingUdpClient.Send(bytCommand, bytCommand.Length)
}

en die als test aanroept met hard-coded strings ( Zodat je de textboxen niet hoeft te accessen )
C#:
1
SendUdpMessage("127.0.0.1", "8080", "Some text" );

Zal je zien dat het waarschijnlijk wel goed gaat.

Verder is het inderdaad goed om even te kijken naar je resource management, ik weet uit mijn hoofd niet exact de API van UdpClient, maar inderdaad goed om die ook op het juiste moment weer op te ruimen/disconnecten. Anders zou het zomaar kunnen zijn dat bij een dubbele connect alsnog iets van een Exception gegooid wordt dat hij al connected is.

[ Voor 15% gewijzigd door Woy op 19-10-2021 16:55 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”

Alle reacties


Acties:
  • +5 Henk 'm!

  • BM
  • Registratie: September 2001
  • Laatst online: 18:33

BM

Moderator Spielerij
Geen idee of dat het probleem is, maar het is wel... raar dat je vanuit je Tick-Event de eventhandler van je button_click aanroept. Ik zou om te beginnen de logica voor het versturen in een losse function zetten, en die aanroepen. Of.. voor nu nog makkelijker, zet die code gewoon in het Tick-event.

En, je hebt het idee dat het bericht wel verstuurd word? Zie je het tick-event daadwerkelijk afgaan? Dat lijkt me stap 1 :)
Moet receivingUdpClient niet gesloten worden na het versturen?

[ Voor 14% gewijzigd door BM op 19-10-2021 07:39 ]

Xbox
Even the dark has a silver lining | I'm all you can imagine times infinity, times three


Acties:
  • +1 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
BM schreef op dinsdag 19 oktober 2021 @ 07:38:
Geen idee of dat het probleem is, maar het is wel... raar dat je vanuit je Tick-Event de eventhandler van je button_click aanroept. Ik zou om te beginnen de logica voor het versturen in een losse function zetten, en die aanroepen. Of.. voor nu nog makkelijker, zet die code gewoon in het Tick-event.

Moet receivingUdpClient niet gesloten worden na het versturen?
Je hebt gelijk.
Ik heb dat ook op die manier geprobeerd. (als eerste zelfs)
Maar voor de eenvoud dacht ik dat het wel goed was om zo hier te posten.

Maar dus ook precies zoals jij omschrijft werkt het helaas niet.

[edit]
En, je hebt het idee dat het bericht wel verstuurd word? Zie je het tick-event daadwerkelijk afgaan? Dat lijkt me stap 1 :)
Ja :)
Moet receivingUdpClient niet gesloten worden na het versturen?
Dat is een goede vraag, maar dat doe ik bij het "handmatig" versturen ook nooit, en het werkt al maanden goed :P

[ Voor 21% gewijzigd door Atmoz op 19-10-2021 07:41 ]


Acties:
  • +3 Henk 'm!

  • MerijnB
  • Registratie: Oktober 2000
  • Laatst online: 22:05
Met iets als Wireshark bekeken of bij jou het pakketje weggaat?

A software developer is someone who looks both left and right when crossing a one-way street.


Acties:
  • +1 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
MerijnB schreef op dinsdag 19 oktober 2021 @ 07:41:
Met iets als Wireshark bekeken of bij jou het pakketje weggaat?
Nee.
Dat is een goede!
Ga ik proberen 8)

[edit]

Hmzzz, ik ben alweer iets verder :)

Met deze code werkt het wel:

code:
1
2
3
4
5
6
      Dim receivingUdpClient2 As UdpClient
        receivingUdpClient2 = New System.Net.Sockets.UdpClient

        receivingUdpClient2.Connect(tbIPSendUDP.Text, tbIPPortUDP.Text)
        Dim bytCommand = Encoding.ASCII.GetBytes(tbTextSendUDP.Text)
        receivingUdpClient2.Send(bytCommand, bytCommand.Length)



Maar wat is dan het verschil tussen de Timer-functie, en dat ik zélf op de knop druk?!

[edit2]

Hmmzz, met dat ik het lees wat ik zelf zojuist typte bedenk ik me ineens: kan het zijn dat het met verschillende Threads te maken heeft?
Dus dat ik als "knop-drukker" in een andere Thread zit dan de Timer leeft? En dat daarom het UDP zenden niet werkt?

[ Voor 68% gewijzigd door Atmoz op 19-10-2021 07:55 ]


Acties:
  • +3 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Atmoz schreef op dinsdag 19 oktober 2021 @ 07:42:
[...]
Hmmzz, met dat ik het lees wat ik zelf zojuist typte bedenk ik me ineens: kan het zijn dat het met verschillende Threads te maken heeft?
Dus dat ik als "knop-drukker" in een andere Thread zit dan de Timer leeft? En dat daarom het UDP zenden niet werkt?
Je kunt UI componenten inderdaad alleen aanroepen vanuit de UI thread, daar krijg je dan een Cross Thread Invocation Exception op.

Het versturen van je pakketje zou eigenlijk ook niet afhankelijk moeten zijn van de UI componenten, maar gewoon helemaal losstaand moeten zijn, en dus ook niet in het Click event geimplementeerd moeten worden.

Om buiten de UI thread toch dingen met de UI te kunnen doen kun je gebruik maken van de Dispatcher, die zorgt dan dat een stukje code alsnog op de UI thread uitgevoerd wordt. Maar het is beter om deze logica niet te verweven met non-ui logica, dus niet in een stukje code die verantwoordelijk is voor netwerk verkeer direct de Dispatcher gebruiken. Je kunt beter een andere manier van control-flow hebben, bijvoorbeeld aan de hand van een return-value, een callback function of een event.

[ Voor 29% gewijzigd door Woy op 19-10-2021 10:08 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
Woy schreef op dinsdag 19 oktober 2021 @ 10:04:
[...]

Je kunt UI componenten inderdaad alleen aanroepen vanuit de UI thread, daar krijg je dan een Cross Thread Invocation Exception op.

Het versturen van je pakketje zou eigenlijk ook niet afhankelijk moeten zijn van de UI componenten, maar gewoon helemaal losstaand moeten zijn, en dus ook niet in het Click event geimplementeerd moeten worden.

Om buiten de UI thread toch dingen met de UI te kunnen doen kun je gebruik maken van de Dispatcher, die zorgt dan dat een stukje code alsnog op de UI thread uitgevoerd wordt. Maar het is beter om deze logica niet te verweven met non-ui logica, dus niet in een stukje code die verantwoordelijk is voor netwerk verkeer direct de Dispatcher gebruiken. Je kunt beter een andere manier van control-flow hebben, bijvoorbeeld aan de hand van een return-value, een callback function of een event.
Thanks voor de uitgebreide (en interessante) info!
Ik ben voor nu blij dat het doet wat het moet doen, want het is maar voor een tijdelijke debug-tool die even een ander ding moet "nadoen" :+

Maar goed om te weten dat ik hier verder moet gaan als ik dit serieus wil gaan gebruiken. Dus thanks daarvoor!

Acties:
  • +1 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Atmoz schreef op dinsdag 19 oktober 2021 @ 12:09:
[...]
Ik ben voor nu blij dat het doet wat het moet doen, want het is maar voor een tijdelijke debug-tool die even een ander ding moet "nadoen" :+
Als je gewoon een functie maakt die 3 string argumenten heeft, ( ip, port en text ), en die aanroept vanuit je Button Click, de waardes van de TextBoxen in een variabele zet in het Change event, en in je timer gewoon dezelfde functie aanroept met de variabelen in plaats van het lezen van de TextBoxen ben je in dit geval klaar, maar zoals gezegd, voor onderhoudbare code kun je het gedrag beter helemaal loskoppelen van de UI.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
Woy schreef op dinsdag 19 oktober 2021 @ 12:26:
[...]

Als je gewoon een functie maakt die 3 string argumenten heeft, ( ip, port en text ), en die aanroept vanuit je Button Click, de waardes van de TextBoxen in een variabele zet in het Change event, en in je timer gewoon dezelfde functie aanroept met de variabelen in plaats van het lezen van de TextBoxen ben je in dit geval klaar, maar zoals gezegd, voor onderhoudbare code kun je het gedrag beter helemaal loskoppelen van de UI.
Bedoel je met mijn eerste stukje "UDP-send-code", dus deze:

code:
1
2
3
receivingUdpClient.Connect(tbIPSendUDP.Text, tbIPPortUDP.Text)
Dim bytCommand = Encoding.ASCII.GetBytes(tbTextSendUDP.Text)
receivingUdpClient.Send(bytCommand, bytCommand.Length)


Dat is een ZEER interessante om te testen :)
Ga ik nu doen 8)

[edit]

Nee, dat werkt helaas niet...
(niet met de UDP-send-code van hierboven)

[ Voor 4% gewijzigd door Atmoz op 19-10-2021 15:19 ]


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Atmoz schreef op dinsdag 19 oktober 2021 @ 12:43:
[...]
Nee, dat werkt helaas niet...
(niet met de UDP-send-code van hierboven)
Dan moet je wat meer debuggen, want ik vermoed dat je nog steeds gewoon een cross-thread exception krijgt, en dus iets niet goed doet.

Dus als ik jou was zou ik eens gaan debuggen, een breakpoint op regel 10 van de gepost code zal waarschijnlijk opheldering geven.

Als je iets van een function maakt
C#:
1
2
3
4
5
6
public void SendUdpMessage(string ip, string port, string text)
{
    receivingUdpClient.Connect(ip, port)
    Dim bytCommand = Encoding.ASCII.GetBytes(text)
    receivingUdpClient.Send(bytCommand, bytCommand.Length)
}

en die als test aanroept met hard-coded strings ( Zodat je de textboxen niet hoeft te accessen )
C#:
1
SendUdpMessage("127.0.0.1", "8080", "Some text" );

Zal je zien dat het waarschijnlijk wel goed gaat.

Verder is het inderdaad goed om even te kijken naar je resource management, ik weet uit mijn hoofd niet exact de API van UdpClient, maar inderdaad goed om die ook op het juiste moment weer op te ruimen/disconnecten. Anders zou het zomaar kunnen zijn dat bij een dubbele connect alsnog iets van een Exception gegooid wordt dat hij al connected is.

[ Voor 15% gewijzigd door Woy op 19-10-2021 16:55 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • +1 Henk 'm!

  • Mavamaarten
  • Registratie: September 2009
  • Laatst online: 16:27

Mavamaarten

Omdat het kan!

Nu nog een kleine opmerking, je maakt een verbinding en stuurt daarheen berichten. Maar wil je effectief elke keer een nieuwe connectie maken of wil je enkel het senden om de x tijd herhalen?

Android developer & dürüm-liefhebber


Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Mavamaarten schreef op dinsdag 19 oktober 2021 @ 16:55:
Nu nog een kleine opmerking, je maakt een verbinding en stuurt daarheen berichten. Maar wil je effectief elke keer een nieuwe connectie maken of wil je enkel het senden om de x tijd herhalen?
Tis UDP

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
Woy schreef op dinsdag 19 oktober 2021 @ 16:53:
[...]

Dan moet je wat meer debuggen, want ik vermoed dat je nog steeds gewoon een cross-thread exception krijgt, en dus iets niet goed doet.

Dus als ik jou was zou ik eens gaan debuggen, een breakpoint op regel 10 van de gepost code zal waarschijnlijk opheldering geven.

Als je iets van een function maakt
C#:
1
2
3
4
5
6
public void SendUdpMessage(string ip, string port, string text)
{
    receivingUdpClient.Connect(ip, port)
    Dim bytCommand = Encoding.ASCII.GetBytes(text)
    receivingUdpClient.Send(bytCommand, bytCommand.Length)
}

en die als test aanroept met hard-coded strings ( Zodat je de textboxen niet hoeft te accessen )
C#:
1
SendUdpMessage("127.0.0.1", "8080", "Some text" );

Zal je zien dat het waarschijnlijk wel goed gaat.

Verder is het inderdaad goed om even te kijken naar je resource management, ik weet uit mijn hoofd niet exact de API van UdpClient, maar inderdaad goed om die ook op het juiste moment weer op te ruimen/disconnecten. Anders zou het zomaar kunnen zijn dat bij een dubbele connect alsnog iets van een Exception gegooid wordt dat hij al connected is.
8)

Gaaf! Thanks. Dát werkt _/-\o_
Weer wat geleerd :9

Interessant hoe dat werkt met GUI en non-GUI dingen :D (en ergens ook wel logisch dat er op sommige gebieden dan iets mis gaan als je ze "verwisselt".
Mavamaarten schreef op dinsdag 19 oktober 2021 @ 16:55:
Nu nog een kleine opmerking, je maakt een verbinding en stuurt daarheen berichten. Maar wil je effectief elke keer een nieuwe connectie maken of wil je enkel het senden om de x tijd herhalen?
Tja, het is maar een hele simpele (tijdelijke) debug-tool, dus zo "diep" had ik er nog niet over nagedacht O-)


[edit]
Reinier schreef op woensdag 20 oktober 2021 @ 08:40:
offtopic:
Gefeliciteerd met je verjaardag, heb je jezelf nog wat CNC apparatuur, laserspullen of Bosch gereedschap cadeau gedaan? ;)
haha, dankjewel :)

Uhm, ik zal binnenkort eens een update posten :P

[ Voor 8% gewijzigd door Atmoz op 20-10-2021 08:42 ]


Acties:
  • 0 Henk 'm!

  • Atmoz
  • Registratie: Juli 2001
  • Laatst online: 01-10 07:55

Atmoz

Techno!!

Topicstarter
Bedoel je daarmee dat het alleen maar op deze manier werkt? (dus niet verbinding in stand houden?)

Acties:
  • +1 Henk 'm!

  • Reinier
  • Registratie: Februari 2000
  • Laatst online: 23:39

Reinier

\o/

offtopic:
Gefeliciteerd met je verjaardag, heb je jezelf nog wat CNC apparatuur, laserspullen of Bosch gereedschap cadeau gedaan? ;)

Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Atmoz schreef op woensdag 20 oktober 2021 @ 08:33:
[...]
Bedoel je daarmee dat het alleen maar op deze manier werkt? (dus niet verbinding in stand houden?)
Ik bedoel dat UDP niet het concept "verbinding" kent. Je stuurt datagrammen naar een peer en die kan datagrammen terugsturen maar er is niet zoiets als "een verbinding" itt wat TCP doet bijvoorbeeld.

Met UDP kun je bijvoorbeeld ook multicasten, iets wat TCP niet kan omdat het een 1 op 1 verbinding moet onderhouden.

Je Connect() call doet waarschijnlijk niet veel (default remote host als je Send() doet ipv SendTo() of zoiets) en as such zal niet veel overhead hebben.

[ Voor 29% gewijzigd door farlane op 20-10-2021 21:11 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1