2

我正在开发一个有服务器的项目,每当客户端连接它时,它就会将其user_id, ip 存储在我使用过的字典中。当我在不同线程之间存储信息时,它正在工作,但是当我尝试从不同线程访问字典时,它工作不正常。

让我清楚我的代码应该做什么:有一个主线程处于活动状态并正在监听客户端,当客户端想要连接时,主线程创建一个子线程并且该线程与客户端连接,客户端发送它一个user_id,this user_id(作为关键对于字典)和Tcpclient(作为值)存储在字典中。此外,一个客户端向服务器发送特定客户端的消息,该消息包含user_id接收方。现在这个客户端连接到一个特定的线程,该线程将检查user_id字典中的 key(),然后将数据发送到该客户端,但字典没有为连接的客户端提供正确的值,即使该客户端已连接,它也只会返回 false。

下面是我的代码示例。

Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.IO


Public Class Mainform

Dim _server As TcpListener
Dim _listOfClients As New Dictionary(Of String, TcpClient)
Public MessageQueue As New Dictionary(Of String, Queue(Of String))
'Dim ClientData As StreamReader

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Try
        Dim port As Integer = 8888

        _server = New TcpListener(System.Net.IPAddress.Any, port)
        _server.Start()
        Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)

    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Private Sub NewClient()
    Dim client As TcpClient = _server.AcceptTcpClient()
    Dim toRec(100000) As Byte
    Dim nss As NetworkStream = client.GetStream()
    nss.Read(toRec, 0, toRec.Length)
    Dim ClientData As String = Encoding.ASCII.GetString(toRec)
    MsgBox("Client Connected: " & ClientData)
    Dim too() As String
    Dim status As Boolean = False
    Dim sendto As String
    Try
        _listOfClients.Add(ClientData, client)

        Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)

        While True
            Dim thisClient As String = ClientData
            Dim ns As NetworkStream = client.GetStream()
            Dim toRecieve(100000) As Byte
            ns.Read(toRecieve, 0, toRecieve.Length)

            Dim txt As String = Encoding.ASCII.GetString(toRecieve)
            'MsgBox(txt)
                too = txt.Split("@") 'server receives data in single string where user_id and message is connected with '@'
                sendto = String.Copy(too(0)) 'this is the user_id of receiver client 
                   If _listofclients.ContainsKey(sendto) Then
                        Dim data As String
                        data = String.Join("#", too)
                        Dim buffer As Byte() = Encoding.ASCII.GetBytes(data)
                        Dim nets As NetworkStream = _listofclients(sendto).GetStream()
                        nets.Write(buffer, 0, buffer.Length)
                   End If
                End While
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub
End Class
4

0 回答 0