2014-07-09 168 views
0

我是Java編程的初學者。我正在嘗試構建一個聊天服務器,其中將有1個服務器和多個客戶端(目前只有2個客戶端)。具有多個客戶端的聊天服務器

邏輯: 說有2個客戶端A和B

當A將消息發送到B,該消息必須首先由服務器處理,然後傳遞到B,反之亦然。

在從A消息應該被顯示爲(實施例)
A中的窗口:您好
B:您好
答:你好嗎?
B:我很好

問題: 當我第一次運行該服務器運行成功。
但是,當我運行客戶端窗口只是卡住,即它不響應。

我想知道的是上面的溝通怎麼做?什麼可以是有效的代碼。

請忽略UI設計。我只想解決上述邏輯

請注意,您可能會發現我的代碼效率低下,並且可能還有一些垃圾代碼。

類名稱:Server.java

package chatserver; 

import java.io.DataInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

import javax.swing.JFrame; 

public class Server { 

    Socket soc; 

    ServerSocket s = null; 

    public Server() throws IOException 
    { 
     try 
     { 
      s = new ServerSocket(6633); 
      while(true) 
      { 
       soc =s.accept(); 
       ServerHandle handle = new ServerHandle(soc); 
       Thread t1 = new Thread(handle); 
       t1.start(); 
      } 
     } 
     catch(Exception e) 
     { 
      System.out.println(e); 
      //should be e.printStackTrace(); 
     } 
     finally 
     { 
      if(s != null) 
      { 
       s.close(); 
      } 
     } 
    } 

    public static void main(String[] args) 
    { 
     // TODO Auto-generated method stub 

     try { 
      new Server(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

服務器處理類
類名稱:ServerHandle.java

package chatserver; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 

public class ServerHandle implements Runnable { 

    Socket s1; 
    BufferedReader reader; 
    PrintWriter write; 
    String msg; 

    public ServerHandle(Socket s1) 
    { 
     this.s1 = s1; 
    } 

    public void run() 
    { 

     try { 
      reader = new BufferedReader(new InputStreamReader(s1.getInputStream())); 
      write = new PrintWriter(new OutputStreamWriter(s1.getOutputStream())); 

      while((msg = reader.readLine()) != null) 
      { 
       write.write(msg); 
      } 
     } 
     catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     finally 
     { 
      try { 
       s1.close(); 
       reader.close(); 
       write.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

客戶端類
類名稱:Client.java

package chatserver; 

import java.awt.Container; 
import java.awt.FlowLayout; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Insets; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import javax.swing.*; 

public class Client implements ActionListener 
{ 
    JTextArea textArea; 
    private JFrame frmChatWindow; 
    private JTextArea textArea_1; 
    JTextField username; 

    JButton submit; 
    JFrame j; 
    JFrame jf; 
    BufferedReader reader; 
    PrintWriter write; 
    String msg; 
    Socket s; 

    public Client() throws Exception, IOException 
    { 
     try 
     { 
      s = new Socket("localhost", 6633); 
      reader = new BufferedReader(new InputStreamReader(s.getInputStream())); 
      write = new PrintWriter(new OutputStreamWriter(s.getOutputStream())); 

      j = new JFrame("PLAIN"); 
      j.setBounds(500, 150, 300, 400); 

      JPanel panel = new JPanel(); 
      j.add(panel); 
      GridBagLayout gb = new GridBagLayout(); 
      panel.setLayout(gb); 

      GridBagConstraints c = new GridBagConstraints(); 

      JLabel label = new JLabel("User Name"); 
      c.gridx = 0; 
      c.gridy = 0; 
      c.fill = GridBagConstraints.HORIZONTAL; 
      c.anchor = GridBagConstraints.NORTHWEST; 
      c.ipadx = 5; 
      c.ipady = 5; 

      c.insets = new Insets(7, 7, 7, 7); 

      panel.add(label, c); 

      username = new JTextField(10); 

      c.gridx = 1; 
      c.gridy = 0; 

      c.fill = GridBagConstraints.HORIZONTAL; 
      c.anchor = GridBagConstraints.WEST; 
      c.ipadx = 5; 
      c.insets = new Insets(7, 7, 7, 7); 

      panel.add(username, c); 

      JLabel password = new JLabel("Password"); 
      c.gridx = 0; 
      c.gridy = 1; 
      c.fill = GridBagConstraints.HORIZONTAL; 
      c.anchor = GridBagConstraints.WEST; 
      c.ipadx = 5; 
      c.insets = new Insets(7, 7, 7, 7); 

      panel.add(password, c); 

      JPasswordField pass = new JPasswordField(10); 
      c.gridx = 1; 
      c.gridy = 1; 
      c.fill = GridBagConstraints.HORIZONTAL; 
      c.anchor = GridBagConstraints.WEST; 
      c.insets = new Insets(7, 7, 7, 7); 

      panel.add(pass, c); 

      submit = new JButton("Submit"); 
      c.gridx = 1; 
      c.gridy = 6; 
      c.fill = GridBagConstraints.HORIZONTAL; 
      c.anchor = GridBagConstraints.WEST; 
      c.insets = new Insets(7, 7, 7, 7); 

      panel.add(submit, c); 

      submit.addActionListener(this); 
      j.setVisible(true); 
      j.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

      while ((msg = reader.readLine()) != null) 
      { 
       display(msg); 
      } 
     } 

     catch (Exception e) 
     { 
      System.out.println(e); 
     } 
     finally 
     { 
      s.close(); 
      reader.close(); 
      write.close(); 
     } 
    } 

    private void display(String msg2) 
    { 
     textArea_1.append("Server" + ": " + msg2); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     // TODO Auto-generated method stub 
     j.dispose(); 
     frmChatWindow = new JFrame(); 
     frmChatWindow.setResizable(false); 
     frmChatWindow.setTitle("Chat Window"); 
     frmChatWindow.setBounds(100, 100, 316, 300); 
     frmChatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     SpringLayout springLayout = new SpringLayout(); 
     frmChatWindow.getContentPane().setLayout(springLayout); 

     textArea = new JTextArea(); 
     springLayout.putConstraint(SpringLayout.WEST, textArea, 10, SpringLayout.WEST, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.SOUTH, textArea, 31, SpringLayout.SOUTH, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.EAST, textArea, 229, SpringLayout.WEST, frmChatWindow.getContentPane()); 
     textArea.setLineWrap(true); 
     frmChatWindow.getContentPane().add(textArea); 

     JButton btnNewButton = new JButton("Send"); 
     springLayout.putConstraint(SpringLayout.NORTH, textArea, 0, SpringLayout.NORTH, btnNewButton); 
     springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton, -58, SpringLayout.SOUTH, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.EAST, btnNewButton, -10, SpringLayout.EAST, frmChatWindow.getContentPane()); 
     frmChatWindow.getContentPane().add(btnNewButton); 

     JButton btnLogout = new JButton("Logout"); 
     springLayout.putConstraint(SpringLayout.NORTH, btnLogout, 10, SpringLayout.NORTH, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.EAST, btnLogout, -10, SpringLayout.EAST, frmChatWindow.getContentPane()); 
     frmChatWindow.getContentPane().add(btnLogout); 

     textArea_1 = new JTextArea(); 
     textArea_1.setEditable(false); 
     textArea_1.append(null); 
     springLayout.putConstraint(SpringLayout.NORTH, textArea_1, 24, SpringLayout.NORTH, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.WEST, textArea_1, 10, SpringLayout.WEST, frmChatWindow.getContentPane()); 
     springLayout.putConstraint(SpringLayout.SOUTH, textArea_1, -19, SpringLayout.NORTH, textArea); 
     springLayout.putConstraint(SpringLayout.EAST, textArea_1, -6, SpringLayout.WEST, btnLogout); 
     frmChatWindow.getContentPane().add(textArea_1); 

     btnLogout.addActionListener(new Test2()); 
     btnNewButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent arg0) 
      { 
       String s = new String(); 
       s = textArea.getText(); 
       sendmsg(s); 
       getwrite(); 
      } 
     }); 
     frmChatWindow.setVisible(true); 
    } 

    private void getwrite() 
    { 
     write.write(username.getText()); 
    } 

    public void sendmsg(String g) 
    { 
     textArea_1.append(username.getText() + " " + ": " + g + "\n"); 
    } 

    class Test2 implements ActionListener 
    { 
     public void actionPerformed(ActionEvent e) 
     { 
      frmChatWindow.dispose(); 
      j.setVisible(true); 
     } 
    } 

    public static void main(String[] args) 
    { 
     // TODO Auto-generated method stub 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       try 
       { 
        new Client(); 
       } 
       catch (IOException e) 
       { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       catch (Exception e) 
       { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 
+0

'請忽略UI設計。'請*刪除*與您的問題無關的所有內容。請參閱http://sscce.org/ –

+0

我已經刪除了服務器中的UI,但客戶端需要UI –

+0

不,它不是。套接字編程與UI無關。 –

回答

1

問題是您正在讀取客戶端輸入和寫入客戶端輸出。基本上,你發送的只是一個Ping服務器發送的任何客戶端。

ServerHandler.java

while((msg = reader.readLine()) != null) 
    { 
     write.write(msg); 
    } 

這與您在客戶端構造函數初始化插口結合使你的UI凍結。

Client.java

s = new Socket("localhost", 6633); 
    reader = new BufferedReader(new InputStreamReader(s.getInputStream())); 
    write = new PrintWriter(new OutputStreamWriter(s.getOutputStream())); 

和右側下方,

while ((msg = reader.readLine()) != null) 
    { 
     display(msg); 
    } 

你的設計是錯誤的了面向連接(TCP),多客戶端聊天服務器。你需要坐下來畫一張關於如何從頭開始寫的圖。

+0

請問我可以如何實現這個目標? –