2

I am working on a project that have a server, whenever a clients connects it stores its user_id, ip in the dictionary which i have used. When I store the information between the different threads it is working but when I try to access the dictionary from different threads, it's not working well.

Let me clear what my code should do: There is one main thread active and listening for clients, when a clients wants to connect, main thread creates a child thread and that thread gets connected with client, client sends it a user_id, this user_id (as key for dictionary) and Tcpclient (as Value) get stored in dictionary. Further one client sends a message for particular client to server, that message contains the user_id for receiver. Now this client is connected with a particular thread which will check the key(user_id) in dictionary and then send the data to that client but dictionary is not giving the correct value for connected clients it just returns false even that client is connected.

Below is my code example.

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
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
krpra
  • 466
  • 1
  • 4
  • 19
  • 2
    I haven't read your question but I can tell you immediately that you should probably use a `ConcurrentDictionary`, which is inherently thread-safe. – jmcilhinney May 10 '18 at 01:31
  • @jmcilhinney yeah but I can also use `synclock` but the main problem is that in the child thread it is not giving the correct value,i.e the dictionary has the `key,value` pair but in the code it returns `false` while checking the key in `dictionary.containskey("key")`. – krpra May 10 '18 at 01:34
  • 1
    So what if you can use `SyncLock`? The `ConcurrentDictionary` class exists to be used in multi-threaded scenarios. Why would you not use it? If you refuse to do something so simple to help yourself, I'm not inclined to spend my time to help with anything else. – jmcilhinney May 10 '18 at 01:50
  • @jmcilhinney I have tried concurrentdictionary also but it's not working,I think there is some mistake in my code,I have provided my code using simple dictionary,please see my code if there is any problem. – krpra May 10 '18 at 02:02
  • I'm not necessarily saying that it will solve your problem. Like I said, I haven't read your question. It should be a given that you're using a `ConcurrentDictionary` in a multi-threaded scenario though, because it will definitely avoid some potential issues. Once you've fixed that, you should edit your question to show us the current code. – jmcilhinney May 10 '18 at 02:05
  • 1
    @krpra - Can you please provide a [mcve] so that we can easily see what the issue is? – Enigmativity May 10 '18 at 02:06
  • @Enigmativity I have explained a simple scenario above.Suppose client A connected with server and sends its user_id to server,Server stores this information in dictionary as dict(user_id,client).Now client A wants to send a message to client B which is also connected to server.But when the thread which is handling the client A search through dictionary for client B,It could't find the key there in dictionary and returning false,this is the problem. – krpra May 10 '18 at 02:12
  • @krpra - Please don't describe anything more. Please provide a [mcve]. Please read that link. I want to be able to copy and paste your code into my coding environment to be able to run it and see the issue you're experiencing. Then I can help. Otherwise it is too hard. Jmcilhenney is saying much the same thing to you - you have to do the hard work to get the help that you need. – Enigmativity May 10 '18 at 02:18
  • @Enigmativity So i have to provide client code also,whole thing is implemented with gui,it will take time to convert it. – krpra May 10 '18 at 02:20
  • @krpra - Correct. It will take time to convert it. That's 100% expected. In doing so you might end up solving your own problem, but if not it'll mean we can solve it quickly for you. Right now the lack of answers is because your question is currently unanswerable. You need to do the work to make it answerable. – Enigmativity May 10 '18 at 02:24
  • @krpra - From the SO help center - "Questions seeking debugging help ("why isn't this code working?") **must** include the desired behavior, a specific problem or error and the **shortest code necessary to reproduce it in the question itself**. Questions without a clear problem statement are not useful to other readers." – Enigmativity May 10 '18 at 02:25
  • @Enigmativity okay, I'll try my best. – krpra May 10 '18 at 02:28

0 Answers0