2012-10-04 4 views
1

Ok, un peu d'arrière-plan. J'écris un client TCP qui obtient des informations de serveurs minecraft. Je veux faire un client qui obtient des informations à partir de 10 serveurs simultanément.Client TCP multithread

Donc, pour cela, je dois utiliser multithreading.

Voici le code que j'ai pour le moment, mais cela ne semble pas fonctionner.

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

Module main 
Private socketclient As New System.Net.Sockets.TcpClient() 

Sub Main() 
    Dim serverList() As String = _ 
    {"ag1.playeoe.com", "lava-craft.net", "play.diamcraft.com", "mc.ecocitycraft.com", "main.kingscrafters.com", "pvp.cursecraft.net"} 

    For i = 0 To serverList.Length - 1 Step 1 
     Console.WriteLine("Connecting to " & serverList(i) & ":" & port & "..") 
     socketclient.BeginConnect(serverList(i), "25565", New AsyncCallback(AddressOf connect), socketclient) 
     Threading.Thread.Sleep(1000) 
    Next 

    Console.ReadLine() 

End Sub 

Public Sub connect(ByVal ar As IAsyncResult) 
    If socketclient.Connected = True Then 
     Console.WriteLine("Connected!") 
     Dim stream As NetworkStream = socketclient.GetStream 
     Dim sendBytes As [Byte]() = {&HFE} 
     Console.WriteLine("Sending Data...") 
     stream.Write(sendBytes, 0, sendBytes.Length) 

     'copied 
     Console.WriteLine("Recieving Response..." & vbNewLine) 
     Dim bytes(421) As Byte 
     stream.Read(bytes, 0, CInt(421)) 

     'Trim Bytes 
     Dim trimbytes(bytes.Length - 3) As Byte 
     Array.Copy(bytes, 3, trimbytes, 0, bytes.Length - 3) 

     'Process output 
     Dim sb As New System.Text.StringBuilder 
     For i As Integer = 1 To 241 Step 2 
      If trimbytes(i) <> 0 Then 
       sb.Append(ChrW(BitConverter.ToInt16(trimbytes, i))) 
      End If 
     Next i 
     Dim message() As String = sb.ToString.Split("§") 

     'Display OutPut 
     Console.WriteLine("----------Response Begin----------") 
     Console.WriteLine(message(0)) 
     Console.WriteLine(message(1)) 
     Console.WriteLine(message(2)) 
     Console.WriteLine("----------Response End----------" & vbNewLine & vbNewLine) 

     socketclient.Close() 
    End If 
End Sub 
End Module 

maintenant cela ne semble pas fonctionner. Je reçois seulement des données du premier serveur mais pas le reste. Quand je le débogue, cela montre que le socket n'est pas ouvert pour les autres serveurs.

est ici la sortie OutPut of the program

+0

Err .. Je ne sais pas VB et ouvert seulement cela par erreur, mais vous avez besoin d'une instance de socket distincte pour chaque connexion au serveur - vous ne pouvez pas utiliser le même à chaque fois. –

+0

À part l'appel à dormir, je ne vois pas du tout de multithreading dans ce code. Faites également votre socket client en haut de votre boucle plutôt qu'en haut du programme. – grieve

+0

@grieve - c'est ce que je pensais. Ré. multithreading, est-ce que le connect-handler n'est pas appelé dans le contexte d'un thread threadpool, (je ne sais pas car je ne connais pas VB :)? –

Répondre

0

Je ne suis pas un expert en VB par tout moyen de sorte que vous devrez jouer avec la syntaxe, mais vous devriez commencer:

Module main 

Sub Main() 
    Dim serverList() As String = _ 
    {"ag1.playeoe.com", "lava-craft.net", "play.diamcraft.com", "mc.ecocitycraft.com", "main.kingscrafters.com", "pvp.cursecraft.net"} 

    For i = 0 To serverList.Length - 1 Step 1 
     Console.WriteLine("Connecting to " & serverList(i) & ":" & port & "..") 
     Dim socketclient As New System.Net.Sockets.TcpClient() 
     socketclient.BeginConnect(serverList(i), "25565", New AsyncCallback(AddressOf  connect), socketclient) 
     Threading.Thread.Sleep(1000) 
    Next 

    Console.ReadLine() 

End Sub 

Public Sub connect(ByVal ar As IAsyncResult) 
    Dim socketClient As CType(ar.AsyncState, System.Net.Sockets.TcpClient) 
    If socketclient.Connected = True Then 
    ... // Everything else can stay the same. 
1

Vous êtes déjà passer le client au BeginConnect comme la variable d'état. Vous pouvez accéder au client spécifique via le IAsyncResult (ar) qui est passé à votre rappel. Juste cast la propriété d'état dans un TcpClient. Désolé, cela suppose que vous avez suivi les conseils des commentateurs et que vous avez créé un nouvel objet client pour chaque adresse de serveur.