2013-03-03 147 views
2

我想創建一個簡單的聊天程序使用java,它包含窗體,客戶端窗體和服務器窗體,客戶端窗體包含一個TextField和一個按鈕(發送按鈕),並且服務器窗體包含一個TextArea。一個簡單的客戶端/服務器聊天程序

當我單擊發送按鈕時,它應該將TextField中的寫入文本發送到服務器表單中的TextArea。

它第一次工作,但當我第二次點擊按鈕時,它將無法正常工作。

這是我的服務器形式使用的代碼:

public class Server extends javax.swing.JFrame implements Runnable { 

    private Thread th; 

    public Server() { 
     initComponents(); 
     th = new Thread(this); 
     th.start(); 
    } 

    // The main method was here 

    @Override 
    public void run() { 

     // Etablir la connexion 
     try { 
      ServerSocket ecoute; 
      ecoute = new ServerSocket(1111); 
      Socket service = null; 
      System.out.println("Serveur en attente d'un client !"); 
      while (true) { 

       service = ecoute.accept(); 
       System.out.println("Client connécté !"); 
       DataInputStream is = new DataInputStream(service.getInputStream()); 
       jTextArea1.setText("Client dit : "+ is.readUTF().toUpperCase()); 
       service.close(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 

     } 
    } 
} 

,這是客戶端形式的代碼:

public class Client extends javax.swing.JFrame { 

    DataOutputStream os; 

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) { 
     try { 
      os.writeUTF(jTextField1.getText()); 
     } catch (IOException ex) { 
      Logger.getLogger(Client.class.getName()).log(Level.SEVERE,null, ex); 
     } 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       Client c = new Client(); 
       c.setVisible(true); 

       try { 
        Socket s = new Socket("localhost", 1111); 
        c.os = new DataOutputStream(s.getOutputStream()); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

} 
+0

「*它第一次工作,但當我第二次點擊按鈕時,它將無法工作。*」。那麼會發生什麼呢?請明確點。 – Lion 2013-03-03 17:54:57

+0

@Lion什麼都沒有發生,它什麼都做,它看起來像操作事件只有一次 – 2013-03-03 18:01:00

+0

沒有例外記錄?這似乎很奇怪.. – ddmps 2013-03-03 18:04:12

回答

2

您的問題是在服務器的代碼: 在服務器端收到來自不同客戶的各種消息, 每個接受,即每個客戶端,你必須創建一個線程來處理它的請求,因爲你使用的是TCP連接。 ( - 你只接受一個請求,然後關閉連接)。

我清理了與代碼套接字無關的部分(即與客戶端中的GUI有關的一些不完整的部分),因此我提出了適用於許多同時客戶端連接的不同版本,並且您可以看到所有消息到達服務器,而不僅僅是第1條消息。

服務器的代碼:

import java.io.*; 
import java.net.*; 


public class Server { 

    public static void run() { 
     try 
     { 
      ServerSocket ecoute; 
      ecoute = new ServerSocket(1111); 
      Socket service = null; 
      System.out.println("serveur en attente d'un client!"); 
      while(true) 
      { 
       service = ecoute.accept(); 
       System.out.println("client connécté!"); 
//    ##call a new thread 
       WorkerThread wt = new WorkerThread(service); 
       wt.start(); 
      } 
     } 
     catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String args[]) { 
     run(); 
    } 
} 


class WorkerThread extends Thread { 
    Socket service; 
    WorkerThread(Socket service) { 
     this.service = service; 
    } 

    public void run() { 
    boolean flag=true; //you can change this flag's condition, to test if the client disconects 
    try 
    { 
     while (flag){ 
      DataInputStream is = new DataInputStream(service.getInputStream()); 
      System.out.println("client dit: " + is.readUTF().toUpperCase()); 
     } 
     service.close(); 
    } 
    catch(IOException e) 
     { 
      e.printStackTrace(); 
     } 
    } 
} 

客戶代碼:

import java.io.*; 
import java.io.*; 
import java.net.*; 
import java.util.logging.*; 


public class Client { 

DataOutputStream os; 

public static void main(String args[]) { 
java.awt.EventQueue.invokeLater(new Runnable() { 

     public void run() { 
       Client c = new Client(); 
     try { 
      Socket s = new Socket("localhost", 1111); 
      c.os = new DataOutputStream(s.getOutputStream()); 
      while (true){ 
       String str = Input.read_string(); 
       c.os.writeUTF(str); 
      } 
     } catch (IOException e) { 
      // TODO auto-generated catch block 
      e.printStackTrace(); 
     } 
      } 
     }); 
    } 
} 

public class Input{ 
    public static String read_string(){ 
     String read=""; 
     try{ 
      read = new BufferedReader(new InputStreamReader(System.in), 1).readLine(); 
     }catch (IOException ex){ 
      System.out.println("error reading from the input stream!"); 
     } 
     return read; 
    } 
} 

之後,你需要,你可能知道,送所有那些到達的消息服務器到聊天室中的所有客戶端。

+0

okey,感謝您的幫助 – 2013-03-03 19:25:39

1

Server代碼,您while(true)節 - 你是在讀完一次之後關閉套接字,而在客戶端則不會重新打開Socket(和新的InputStream)。我建議你在while(true)部分有另一個循環,它將繼續讀取並顯示新的數據,直到達到EOF。

+0

我不知道我在哪裏使用其他while(true)loop – 2013-03-03 18:54:38

+0

他不需要在客戶端重新打開一個套接字,因爲他使用的是TCP。他需要在服務器端繼續處理消息,並且服務器端的一個簡單的(真正的)循環是不夠的,因爲它只支持一個客戶端... – 2013-03-03 19:12:54