DiamondKid Ответов: 1

Как предотвратить замораживание формы (не удается получить входящие данные) - VB.NET спросите


I am developing a two-player Quiz bee game LAN-Based. The players takes turn one at a time. A player will click a button to pick a question. On the first two turns, sending and receiving of data are working but on the third turn the other player didn't receive the incoming data.

Anyone can help me to avoid this problem?


Что я уже пробовал:

**Variables for `UDPClient`**

    Public Module Server
        Public publisher As New Sockets.UdpClient(0)
        Public subscriber As New Sockets.UdpClient(54545)
    End Module

**Here is my code for TheGame.vb (Receiving data)**

    Private Sub tmrUDP_Tick(sender As Object, e As EventArgs) Handles tmrUDP.Tick
        Try
            Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 0)
            Dim receiveBytes() As Byte = subscriber.Receive(ep)
            lblReceive.Text = ASCII.GetString(receiveBytes)

            If lblReceive.Text = "b1" Then
                bttn1.BackgroundImage = My.Resources.Bee_Button_Blue
                btn1 = False
                bluebtn1 = True
                UncheckRB()
                bttn1.Enabled = False
                bttn1.Visible = False
                pcbxb1.Visible = True
                ShowHideColorPanel()
                enableButtons()
                btnused1 = True

                publisher.Close()
                subscriber.Close()
                '=====================
            ElseIf lblReceive.Text = "b2" Then
                bttn2.BackgroundImage = My.Resources.Bee_Button_Blue

                btn2 = False
                bluebtn2 = True
                UncheckRB()
                bttn2.Enabled = False
                bttn2.Visible = False
                pcbxb2.Visible = True
                ShowHideColorPanel()
                enableButtons()
                btnused2 = True
                '=====================

    'same code until "b25"

    ElseIf lblReceive.Text = "r1" Then
                bttn1.BackgroundImage = My.Resources.Bee_Button_RED

                btn1 = False
                redbtn1 = True
                UncheckRB()
                bttn1.Enabled = False
                bttn1.Visible = False
                pcbxr1.Visible = True
                ShowHideColorPanel()
                enableButtons()
                btnused1 = True
                '=====================
            ElseIf lblReceive.Text = "r2" Then
                bttn2.BackgroundImage = My.Resources.Bee_Button_RED

                btn2 = False
                redbtn2 = True
                UncheckRB()
                bttn2.Enabled = False
                bttn2.Visible = False
                pcbxr2.Visible = True
                ShowHideColorPanel()
                enableButtons()
                btnused2 = True
                '=====================
    'same code until r25
    End Sub

**TheGame_Load**

    Private Sub TheGame_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    subscriber.Client.ReceiveTimeout = 100
        subscriber.Client.Blocking = False
    End Sub

**Here is the Sending Data event**(*button event from another `Form` to submit answer*)

    Private Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
    If btn1 = True And TheGame.lblColor.Text = "Blue" Then

                            publisher.Connect(TheGame.lblIPother.Text, TheGame.lblPort.Text)
                            Dim sendByte() As Byte = ASCII.GetBytes("b1")
                            publisher.Send(sendByte, sendByte.Length)

                            AddScore()
                            TheGame.bttn1.BackgroundImage = My.Resources.Bee_Button_Blue
                            Me.Hide()
                            btn1 = False
                            bluebtn1 = True
                            UncheckRB()
                            TheGame.bttn1.Enabled = False
                            btnused1 = True
                            disableButtons()
                            ShowHideColorPanel()

    ElseIf btn1 = True And TheGame.lblColor.Text = "Red" Then

                            publisher.Connect(TheGame.lblIPother.Text, TheGame.lblPort.Text)
                            Dim sendByte() As Byte = ASCII.GetBytes("r1")
                            publisher.Send(sendByte, sendByte.Length)
                            AddScore()
                            TheGame.bttn1.BackgroundImage = My.Resources.Bee_Button_RED
                            Me.Hide()

                            btn1 = False
                            redbtn1 = True
                            UncheckRB()
                            TheGame.bttn1.Enabled = False
                            btnused1 = True
                            disableButtons()
                            ShowHideColorPanel()
    'same code until `btn25`
    End Sub

[no name]

"другой игрок не получил входящие данные", вероятно, потому, что вы используете"UdpClient".

DiamondKid

Что я должен использовать?

[no name]

Я бы использовал протокол, который сам обеспечивает доставку пакетов данных, вместо того чтобы ждать протокола, который отбрасывает пакеты по прихоти.

1 Ответов

Рейтинг:
2

Graeme_Grant

Приложения, которые кажутся "заблокированными", обычно указывают на то, что в потоке пользовательского интерфейса активна длительная задача, блокирующая канал сообщений пользовательского интерфейса. Если вы действительно используете код Сэма,то задачи UDP находятся в потоке sperate.

Для отладки этого, когда возникает долгая пауза/"приложения заблокированы" событие, нажмите кнопку против паузу и посмотреть, когда приложение занято. Если вы не приземляетесь на код, продолжайте наступать, пока не сделаете это. Вы точно увидите, где находится одна из ваших проблем.


DiamondKid

Я сделал то, что вы сказали, и это указывает мне на этот код

Private Sub tmrUDP_Tick(sender As Object, e As EventArgs) Handles tmrUDP.Tick
        Try
            Dim ep As IPEndPoint = New IPEndPoint(IPAddress.Any, 0)
            Dim receiveBytes() As Byte = subscriber.Receive(ep)
            lblColor.Text = ASCII.GetString(receiveBytes)

            If lblColor.Text = "b" Then
                btnBlue.Visible = False
            ElseIf lblColor.Text = "r" Then
                btnRed.Visible = False
            End If

        Catch ex As Exception

        End Try
    End Sub


Приведенный выше код предназначен для выбора цвета игрока (синий или красный). Если игрок выбрал синий цвет, синяя кнопка исчезнет на форме windows другого игрока.

Graeme_Grant

Использование таймера для" просмотра", а не потока приемника для" прослушивания " - большая ошибка. Вы испытаете потерю пакетных данных. Другая проблема заключается в том, что входящие данные могут не соответствовать тому, что вы ожидаете в данный момент.

Пример Сэма работает не так. Получатель не должен заботиться о том, какие данные поступают, а просто передать их логике состояния, чтобы решить, как они должны быть обработаны.

Кроме того, вы понимаете, как работает UDP? Протокол Пользовательских Дейтаграмм-Википедия[^]

DiamondKid

Я использовал этот таймер из LAN-чата с помощью udpclient tutorial. Я попробовал код Сэма, но куда идет сообщение?

Graeme_Grant

Вы должны написать приложение UPD message state machine.