2014-02-13 35 views
0

我們的代碼現在執行的是客戶端和服務器,客戶端可以通過服務器發送消息。問題是,我們需要做客戶端客戶端,因此客戶端的消息必須直接進入其他客戶端的聊天框。我們只能在服務器聊天室中看到他們正在討論的內容,而不是在客戶端的聊天室中。顯然它只能做客戶端服務器。請幫忙?謝謝!如何在我們的Java代碼中使客戶PM消息?

SampleServer.java

 /* 
     * To change this template, choose Tools | Templates 
     * and open the template in the editor. 
     */ 

     /** 
     * 
     * @author Kim 
     */ 
     import java.io.*; 
     import java.net.*; 
     import java.awt.*; 
     import java.awt.event.*; 
     import javax.swing.*; 
     import java.util.*; 
     import java.lang.Object.*; 


     public class SampleServer{ 

      private ObjectOutputStream output; //output stream->flows from my computer to the other computer 
      private ObjectInputStream input; //input stream->receive stuff 
      private ObjectInputStream name; //input stream->receive stuff 
      private Socket connection; //socket variable 
      private String user; 
      private String ip; 
      private PrintWriter p; 
      private BufferedReader fromC; 
      private serverTest server; //Saves the server test to append messages. 

      //constructor 
      public SampleServer(Socket c, String username, String userip, serverTest t){ //EDITED!! 
       connection = c; 
       server = t; 
       ip= userip; 
       user= username;    
       //setupStreams(); //set up output and input stream 

       try{ 
       output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to 
       output.flush(); //bytes of information that is send to other person (leftover) 
       input = new ObjectInputStream(connection.getInputStream()); //receive messages 
       showMessage("\n Streams are now setup! \n"); 
       }catch(IOException ioException){ 
        ioException.printStackTrace(); 

       } 

      } 

      public void run() //This method gets called when Thread starts running 
      { 
       whileChatting(); 
       closeAll(); 
      } 

      //get stream to send and receive data 
      private void setupStreams(){ 
       try{ 
       output = new ObjectOutputStream(connection.getOutputStream()); //computer who we communicate to 
       output.flush(); //bytes of information that is send to other person (leftover) 
       input = new ObjectInputStream(connection.getInputStream()); //receive messages 
       showMessage("\n Streams are now setup! \n"); 
       }catch(IOException ioException){ 
        ioException.printStackTrace(); 

       } 
      } 

      //actual chat conversation 
      private void whileChatting(){ 
       String message = "You are now connected!"; 
       sendMessage(message); 
       do{ 
        try{ 
         message = (String) input.readObject(); //views it as an object and make sure it's a string 
         showMessage("\n" + message); 
        }catch(Exception e){ 
         //showMessage("\nError!"); 
        } 
       }while(!message.equals("CLIENT - END")); 

      } 

      //close streams and sockets 
      public void closeAll(){ 
       showMessage("\n Closing connection... \n"); 
       try{ 
        output.close(); 
        input.close(); 
        connection.close(); 
       }catch(IOException ioException){ 
        ioException.printStackTrace(); 

       } 
      } 

      //send message to other computer 
      public void sendMessage(String message){ 
       try{ 
        output.writeObject("SERVER - " +message); //sends the mesage to the output stream 
        output.flush(); //push extra bytes to user 
       }catch(IOException ioException){ 
        showMessage("\n ERROR!"); //put in the chat area 

       } 

      } 

      //updates chatWindow 
      private void showMessage(String text){ 
       server.showMessage(text); 
      } 

     } 

ServerTest.java

 /* 
     * To change this template, choose Tools | Templates 
     * and open the template in the editor. 
     */ 

     /** 
     * 
     * @author Kim 
     */ 
     import java.io.*; 
     import java.net.*; 
     import java.awt.*; 
     import java.awt.event.*; 
     import javax.swing.*; 
     import java.util.*; 
     import java.lang.Object.*; 

     public class serverTest extends JFrame { 
      private JTextField userText; //message variable area 
      private JTextArea chatWindow; //display the conversation 
      private ServerSocket server; //server variable 
      private Vector<String> users; 
      private Vector<String> ips; 
      private JTextArea conList; 
      private ArrayList<SampleServer> connections = new ArrayList<SampleServer>(); 

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

      public serverTest() 
      { 
       super("Instant Messenger"); 
       userText = new JTextField(); //text field 
       userText.addActionListener(
         new ActionListener(){ 
          public void actionPerformed (ActionEvent event){ 
           sendMessage(event.getActionCommand()); //sends the message 
           userText.setText(""); 
          } 
         } 
       ); 
       add(userText, BorderLayout.SOUTH); 
       users = new Vector(); 
       ips = new Vector(); 
       chatWindow = new JTextArea(); 
       conList = new JTextArea(); 
       conList.setEditable(false); 
       add(new JScrollPane(chatWindow)); 
       add(new JScrollPane(conList), BorderLayout.EAST); 
       conList.append(" ONLINE USERS \n"); 
       setSize(300, 150); 
       setDefaultCloseOperation(EXIT_ON_CLOSE); 
       setVisible(true); 

       try { 
        server = new ServerSocket(6789, 100); //port number and only 100 can connect to the server 
        while(true){ 
         try{ 
          showMessage("Waiting for someone to connect...\n"); 
          Socket connection = server.accept(); //once someone asked for connection, accepts this 
          //showMessage("Now connected to "+connection.getInetAddress().getHostName()); //converts the ip address to string 

          ips.add(connection.getInetAddress().getHostName()); // adds ip address of client to ips vector 

          BufferedReader fromC = new BufferedReader(new InputStreamReader(connection.getInputStream())); // gets what client sent through printwriter - username 
          String s = new String(fromC.readLine()); // saves as string 
          users.add(s); // saves username of client to users vector 
          String con = (connection.getInetAddress().getHostName()); 
          showMessage(s + "/" + con + " has connected."); 

          Iterator c = users.iterator(); // username iterator 
          Iterator b = ips.iterator(); // ip address iterator 

          conList.setText(""); 

          while(c.hasNext()) { 

           String d = (c.next()).toString(); // gets next element in users vector 
           String e = (b.next().toString()); // gets next element in ips vector 
           conList.append(d + "\n"); // displays username in online users list 
           conList.append("(" + e + ")\n\n"); // displays ip in online users list 
          } 
          final SampleServer se = new SampleServer(connection, s, con, this); 
          Thread t = new Thread(new Runnable(){ 
           public void run() 
           { 
            se.run(); 
           } 
          }); 
          t.start(); 
          connections.add(se); 

         }catch(EOFException eofException){ 
          showMessage("\n Server ended the connection!"); 
         } 
        } 

       }catch(IOException ioException){ 
        ioException.printStackTrace(); 
       } 
      } 

      public void closeAll() 
      { 
       while (!connections.isEmpty()) 
       { 
        connections.get(0).closeAll(); 
        connections.remove(0); 
       } 
      } 

      public void sendMessage(String text) 
      { 
         showMessage("\n SERVER - " + text); 
       for (SampleServer s : connections) 
       { 
        s.sendMessage(text); 
       } 
      } 

      public void showMessage(final String text) 
      { 
       SwingUtilities.invokeLater(//updats GUI or threads 
         new Runnable(){ 
          public void run(){ 
           chatWindow.append(text); //add string at the end of the chatWindow 
          } 
         } 
       ); 
      } 
     } 

clientTest.java

 /* 
     * To change this template, choose Tools | Templates 
     * and open the template in the editor. 
     */ 

     /** 
     * 
     * @author Kim 
     */ 
      import javax.swing.*; 

      public class clientTest { 

       public String userName; 
       private static JFrame frame = new JFrame("Messenger"); 

        private static String getUsername() { 
        return JOptionPane.showInputDialog(
         frame, 
         "Enter Username:", 
         "Instant Messenger", 
         JOptionPane.QUESTION_MESSAGE); 
       } 

       public static void main(String[] args){ 

        String username = getUsername();//getting username 
        SampleClient client;      
        client = new SampleClient("localhost", username); //localhost 

        client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        client.startRunning(); 
       } 

      } 

sampleClient.java

 /* 
     * To change this template, choose Tools | Templates 
     * and open the template in the editor. 
     */ 

     /** 
     * 
     * @author Kim 
     */ 
     import java.io.*; 
     import java.net.*; 
     import java.awt.*; 
     import java.awt.event.*; 
     import javax.swing.*; 

     public class SampleClient extends JFrame{ 

     private JTextField userText; 
     private JTextArea chatWindow; 
     private ObjectOutputStream user; 
     private ObjectOutputStream output; 
     private ObjectInputStream input; //from the server 
     private String message = ""; 
     private String serverIP; 
     private Socket connection; 
     private String name; 
     private JTextArea contacts; 
     private PrintWriter toS; 

     //constructor 
     public SampleClient(String host, String username){ 
      super("Client"); 
      serverIP = host; 
      name = username; 
      userText = new JTextField(); 
      userText.setEditable(false); //not allowed to type while no one is connected 
      userText.addActionListener(
       new ActionListener(){ 
        public void actionPerformed(ActionEvent event){ 
         sendMessage(event.getActionCommand()); 
         userText.setText(""); 

        } 

       } 
       ); 
      add(userText, BorderLayout.SOUTH); 
      contacts = new JTextArea(); 
      chatWindow = new JTextArea(); 
      add(new JScrollPane(contacts), BorderLayout.EAST); //scroll 
      contacts.append(" ONLINE CONTACTS \n"); 
      add(new JScrollPane(chatWindow), BorderLayout.CENTER); //scroll 
      setSize(300, 150); 
      setVisible(true); 
     } 

     //connect to server 
     public void startRunning(){ 
      try { 

       connectServer(); 
       setupStreams(); 
       whileChatting(); 

      }catch(EOFException eofException){ 
       showMessage("\n Client terminated connection"); 
      }catch (IOException ioException){ 
       ioException.printStackTrace(); 
      }finally{ 
       closeAll(); 
      } 
     } 

     //connectServer 
     private void connectServer() throws IOException{ 
      showMessage("Attempting connection... \n"); 
      connection = new Socket(InetAddress.getByName(serverIP), 6789); //passes to an IP Adrdress and Port Number 
      showMessage("Connected to:" + connection.getInetAddress().getHostName()); //prompt 
      toS = new PrintWriter(connection.getOutputStream(), true); 
      toS.println(name); 

     } 

     //set up streams for sending and receive the messages 
     private void setupStreams()throws IOException{ 
      output = new ObjectOutputStream(connection.getOutputStream()); 
      output.flush(); 
      input = new ObjectInputStream(connection.getInputStream()); //receive messages 
      showMessage("\n Streams are connected"); 

     } 

     //actual chat 
     private void whileChatting()throws IOException{ 
      ableToType(true); 
      do{ 
       try{ 
        message = (String) input.readObject(); 
        showMessage("\n" +message); 
       }catch(ClassNotFoundException classNotFoundException){ 
        showMessage("\n ERROR!"); 
       } 
      }while(!message.equals("SERVER - END")); 
     } 

     //close sockets and streams 
     private void closeAll(){ 
      showMessage("\n Closing connections.."); 
      ableToType(false); 
      try{ 
       output.close(); 
       input.close(); 
       connection.close(); 
      }catch(IOException ioException){ 
       ioException.printStackTrace(); 
      } 
     } 

     //send messages to server 
     private void sendMessage(String message){ 
      try{ 
       output.writeObject("\n" + name + ": " + message); 
       output.flush(); //push bytes 
       showMessage("\n" + name + ": " + message); 

      }catch(IOException ioException){ 
       chatWindow.append("ERROR!"); 

      } 
     } 

     //Update chatWindow 
     private void showMessage(final String m){ 
      SwingUtilities.invokeLater(
        new Runnable(){ 
         public void run(){ 
          chatWindow.append(m); //appear at the end of the conversation 

         } 
        } 
      ); 

     } 

     //permission to type to for user 
     private void ableToType(final boolean tof){ 
      SwingUtilities.invokeLater(
        new Runnable(){ 
         public void run(){ 
          userText.setEditable(tof); 
         } 
        } 
      ); 
     } 
     } 
+0

如果問題只是關於誰可以「看到」消息,那麼我只需在消息中添加更多元數據而不是翻轉整個系統以實現直接的對等連接。一個'私人'布爾標誌可能已經足夠了,然後基於該標誌,客戶端應用程序可以決定將其顯示在服務器窗口或私人窗口中。 – Gimby

回答

0

用TCP很難實現它,因爲如果你在鄰居中有10個客戶端,那麼你必須爲每個客戶端打開10個端口。如果你認爲你可以處理它,那麼你的系統上應該同時有ServerSocketSocket,這意味着並行地在流上進行監聽和寫入。

但是這可以通過UDP來實現,但是有很多限制,UDP並不容易。

相關問題