2016-04-03 34 views
1

Bir sunucu-istemci uygulama setim var. (ÖDEV)Sohbet: Bir sunucudaki tüm istemcilere mesaj gönderme

Şimdiye kadar, birden fazla istemcinin sunucuya nasıl bağlanacağını ve sunucunun istemcilerin gönderdiği iletileri toplamasını ve sunucunun istemcinin iletisini istemciye geri göndermesini ve görüntülemesini sağlamayı öğrendim sohbet bölmesinde.

Sorunum, birden çok istemciye ileti göndermeye çalışıyor. Sadece ServerSocket ve Socket kitaplıklarını kullanabiliyorum.

Sunucuya bağlı 2 istemcim var mı? Bir müşteri bir mesaj gönderir, mesaj müşterinin sohbetinde görüntülenir. İkinci istemci bir mesaj gönderir, ilk müşteri bunu almaz ve ikinci müşterinin sohbet penceresi ilk müşterinin mesajını gösterir.

Esasen sunucu, ilgili istemcinin sohbet kutusunda görüntülenmediği en son iletiyi gönderiyor ve neden ya da nasıl olduğuna dair hiçbir fikrim yok. sunucu-istemci iletişimi için

Kodu:

Class CommunicationThread extends Thread { 

    //Vector containing all client sockets currently connected 
    //Held offsite, here for clarity 
    public Vector<Socket> socketVector; 

    public CommunicationThread (Socket clientSoc, Server ec3, Vector<Socket>socketVectorg) 
    { 
    //add new socket to vector, start thread 
    clientSocket = clientSoc; 
    socketVectorg.add(clientSocket); 
    this.socketVector = socketVectorg; 
    gui = ec3; 
    } 

    public void run() 
    { 
    System.out.println ("New Communication Thread Started"); 

    try { 
     //Client's chat box (output) 
     PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), 
       true); 

     //Input line from client 
     BufferedReader in = new BufferedReader(
       new InputStreamReader(clientSocket.getInputStream())); 

     String inputLine; 

     while ((inputLine = in.readLine()) != null) { 
      System.out.println("Server: " + inputLine); 
      gui.history.insert(inputLine + "\n", 0); 

      //*************HERE IS MY ISSUE******************* 
      for(Socket s : socketVector){ 
       out = new PrintWriter(s.getOutputStream(), 
         true); 
       out.println(inputLine); 
      } 

      if (inputLine.equals("Bye.")) 
       break; 

      if (inputLine.equals("End Server.")) 
       gui.serverContinue = false; 

     } 

     out.close(); 
     in.close(); 
     clientSocket.close(); 
    } 
    catch (IOException e) 
    { 
    System.err.println("Problem with Communication Server"); 
    //System.exit(1); 
    } 
    } 
} 

ben "dışarı" üzerine yazmasını ediyorum ama ben test ediyorum 'o benim kodda yani bu benim sorunu olduğunu düşünmüyorum biliyorum.

Sorunum, yukarıdaki kodda işaretlenmiştir. Vektör, soket kimliğini doğru bir şekilde kaydeder ve vektörü temel alan yeni bir Yazıcı Yazıcısı oluşturduğumdan, yalnızca ilgili istemcinin çıktı alanını alacağını varsayardım, ancak bunu yapmaz.

Sezgim, çıktının işlenmesi veya kapatılmasıyla ilgili bir sorun olduğudur, ancak dürüst bilmiyorum.

Herhangi bir öneri takdir edilir.

+2

Oh, efendim, lütfen kurucudaki bir Thread'deki 'start()' yi çağırmayın. Nesne henüz tam olarak inşa edilmedi. Yapıcı döndükten sonra 'start()'; Bu davranışı zorlamak gerekiyorsa statik bir yöntem (bir fabrika yöntemi) kullanın. – markspace

+0

düzeltildi ve not edildi, teşekkürler – mrybak3

+1

Sorununuzun bir kısmı, her giriş satırı için yeni bir 'PrintWriter 'oluşturmanız olabilir. Bu "kapalı" görünüyor. Ayrıca, bu sınıfta GUI kodunu görüyorum. Normalde GUI, sunucuda değil istemcide çalışır. Bu yüzden yukarıdaki kodunuzun sunucu kodu olduğunu doğrulamak istiyorum. Doğru? – markspace

cevap

1

Sorun şu ki, istemci soketindeki giriş ve çıkış çalışmalarını aynı yerde yapmak istediğiniz ve buna gerek yok. İstemci soketinin çıktı akışı GUI dizisine ve hepsi tek bir yere yazılabilir. Gerekirse ve hepsine yanıt vermek istediğinizde, koleksiyonda yineleyin (muhtemelen String'in bir istemci kimliği olan HashMap<String, OutpuStream>) ve mesajları gönderin.

+0

İlk 2 cümlenizi tam olarak anlamıyorum. Müşteri GUI iş parçacığına nasıl yazılabilir? şu an yaptığım şey değil mi? Olursa yanlış anlaşılma için özür dilerim. Sadece açıkçası, gerçek soketler yerine "çıkış" lar saklamayı mı düşünüyorsunuz?Bunu sabahları deneyeceğim ve işe yarayacaksa iyi bir öneride bulunacağından emin olacağım. Ayrıca kesinlikle bir HashMap kullanacaktır, teşekkürler. – mrybak3

+1

@ mrybak3: Evet, OutputStream veya bir PrintStream'e sarılmış bir OutputStream içeren bir yardımcı program sınıfının daha olası nesneleri. –

+0

Harika, çok teşekkür ederim – mrybak3

İlgili konular