【问题标题】:Vb.net Network Programming cant add new user to listboxVb.net网络编程无法将新用户添加到列表框
【发布时间】:2014-01-09 02:51:27
【问题描述】:

我开始构建 TCP 服务器/客户端及其协议,但它们是一些我无法理解的问题,因为它的文档较少,而且它也与跨线程有关。我也尽量避免非法的交叉线程。到目前为止,我在我的文本框上工作以更新 raiseStatus 事件的状态,无论如何我不知道如何使用列表框来做到这一点。通常我无法使用我这样构建的协议发送和接收我想要的所有消息:LOGIN:NAK。这意味着用户 NAK 登录,我的程序可以与此协议很好地通信,因为我还有更多要实现。我只是在客户端使用此命令时将 NAK 添加到 listbox1 时卡住了。

我的服务器端代码:

这是我的 form1 类

Public Class Form1

Dim portToListen As Integer = 700
Dim WithEvents manager As ClientMananger
Dim WithEvents M_Client As Client

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    manager = New ClientMananger(Me)
    manager.Listen(portToListen)

End Sub

Private Sub manager_Status(message As String) Handles manager.Status
    txtStatus.Text &= message & vbNewLine
End Sub

End Class

这是我的类 ClientManager

Public Class ClientMananger

Dim tcpListener As TcpListener
Dim listenThread As Thread

Dim clientList As New List(Of Client)

Public Event Status(message As String)
Public Event Connect(client As Client)
Public Event Disconnect(client As Client)

Public Sub Listen(port As Integer)
    tcpListener = New TcpListener(port)

    '' Start thread for listening for new income socket
    listenThread = New Thread(AddressOf ListenProc)
    listenThread.Start()
End Sub

Private Sub ListenProc()
    RaiseStatus("Listen to port ...")

    '' Continously listen to certain port
    tcpListener.Start()
    While True
        Dim incomeClient As New Client(tcpListener.AcceptSocket(), Me)

        '' Income connection has been made
        RaiseStatus("Client attempt to connect ...")

        '' Send welcome message to client
        incomeClient.Send("Welcome to RAMA Hospital Chat Server!")
        clientList.Add(incomeClient)

    End While
End Sub

Public Sub SendAll(client As Client, msg As String)
    For Each c As Client In clientList
        If client IsNot c Then
            c.Send(msg)
        End If
    Next
End Sub

Public Sub SendTo(sender As Client, rv As String, msg As String)
    For Each c As Client In clientList
        If c.name = rv Then
            c.Send("PRIVATE:" & sender.name & ":" & msg)
        End If
    Next
End Sub

#Region "GUI"
Dim form As Form

'' GUI
Public Sub New(form As Form)
    Me.form = form
End Sub

Private Sub RaiseStatus(txt As String)
    form.Invoke(RaiseStatusInvoker, txt)
End Sub

Private Delegate Sub RaiseStatusDelegate(txt As String)
Private Sub RaiseStatusFunc(txt As String)
    RaiseEvent Status(txt)
End Sub
Private RaiseStatusInvoker As New RaiseStatusDelegate(AddressOf RaiseStatusFunc)

#End Region

End Class

这是我无法使其工作的类客户端,无论如何我可以将我的 [part(1) 表示从客户端拆分的用户名] 部分 (1) 添加到 listbox1 吗?我使用了 form1.listbox1.item.add(part(1)) 但它不起作用它也没有显示任何错误。

Public Class Client

Dim sck As Socket
Dim msgThread As Thread
Public name As String = ""
Dim parent As ClientMananger
Private _socket As Socket
Private _client As Client

Public Event Status(message As String)

Public Sub New(sck As Socket, parent As ClientMananger)
    Me.sck = sck
    Me.parent = parent

    '' Listen to incoming message
    msgThread = New Thread(AddressOf ReceiveMessage)
    msgThread.Start()
End Sub

Public Sub Send(message As String)
    Dim msgByte() As Byte = System.Text.ASCIIEncoding.ASCII.GetBytes(message)
    sck.Send(msgByte, SocketFlags.None)
End Sub

Private Sub ReceiveMessage()
    Try
        Dim buffer(1000) As Byte
        Dim size As Integer = 0
        Dim msg As String

        Do
            size = sck.Receive(buffer, SocketFlags.None)
            If size > 0 Then
                msg = System.Text.ASCIIEncoding.ASCII.GetString(buffer, 0, size)
                HandleMessage(msg)
            End If
        Loop While size > 0
    Catch ex As SocketException
        '' Disconnect
    End Try
End Sub

Private Sub HandleMessage(msg As String)

    Dim part() As String = msg.Split(":")
    Dim command As String = part(0).ToUpper()

    If command = "LOGIN" Then
        Me.name = part(1)

        **Form1.listbox1.item.add(part(1))**


        MessageBox.Show(part(1) + " Had been add to the server!!!")
    ElseIf command = "ALL" Then
        parent.SendAll(Me, part(1))
    ElseIf command = "PRIVATE" Then
        parent.SendTo(Me, part(1), part(2))
    End If

End Sub
End Class

很抱歉发布了很多代码,但真的无法完成这项工作,请提前帮助您,如果您想获得我的客户端代码,我可以在这里发布。

【问题讨论】:

    标签: vb.net multithreading tcp network-programming


    【解决方案1】:

    编辑:

    经过讨论,很明显你不能从这个方法中的线程访问列表框,根据this article,它是不安全的。相反,您必须使用 ClientManager 类中的 Status 事件。您将需要进行三个简单的编辑:

    首先,更新 Form1 中的状态处理程序以将文本添加到新列表框。 (请相应更改列表框名称)

    Private Sub manager_Status(message As String) Handles manager.Status
        ' CODE ADDED
        ' added code to add the text to a listbox, instead of a textbox
        ListBox1.Items.Add(message)
    End Sub
    

    其次,将您的 ClientManager RaiseStatus 子设为公开。它需要是公共的,以便客户端类可以在第三步中使用它。

    ' CODE ADDED
    ' change access modifier to public
    Public Sub RaiseStatus(txt As String)
        form.Invoke(RaiseStatusInvoker, txt)
    End Sub
    

    最后,更新 Client Class.HandleMessage sub 以使用父级的 RaiseStatus 事件(您在上一步中刚刚公开的事件)

    Private Sub HandleMessage(msg As String)
    
        Dim part() As String = msg.Split(":")
        Dim command As String = part(0).ToUpper()
    
        If command = "LOGIN" Then
            Me.name = part(1)
    
            ' This is unsafe, you cannot access the parent thread this way
            '**Form1.listbox1.item.add(part(1))**
    
            ' CODE ADDED
            ' this is safe, using the event handler.
            ' parent.RaiseStatus("hello world")
            parent.RaiseStatus(part(1))
    
        ElseIf command = "ALL" Then
            parent.SendAll(Me, part(1))
        ElseIf command = "PRIVATE" Then
            parent.SendTo(Me, part(1), part(2))
        End If
    End Sub
    

    【讨论】:

    • HI thx 帮助语法错误无论如何在 m 更改为 form1.listbox1.items.add(part(1)) 之后,我的 listbox1 的列表项中没有任何内容。 MessageBox.show() 正确,但代码现在添加没有错误,但仍不显示结果。我认为真正的问题不是那个错误。有什么建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多