2014-10-26 132 views
0

我試圖做一個小聊天程序,但它真的不想工作。我的服務器和客戶端大部分是相同的:他們創建一個新的套接字和一個新的聊天(GUI)。有人能幫我找到我犯的錯誤嗎?Java ServerSocket/Socket聊天程序

服務器代碼:

import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 

import java.net.Socket; 
import java.net.ServerSocket; 

public class Server { 
    private  Chat   ch  = null; 
    private  ServerSocket server = null; 
    private  Socket   s  = null; 
    private  BufferedReader in  = null; 
    private  BufferedWriter out  = null; 

    public Server() { 
     try { 
      server = new ServerSocket(1792); 
      s = server.accept(); 
      in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
      out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
      ch = new Chat("Server", out); 
     } catch (IOException ioe) { 

     } 

     new Thread(new Runnable() { 
      public void run() { 
       while (true) { 
        try { 
         String line = in.readLine(); 
         ch.showString(line); 
        } catch (IOException e) { 
         System.exit(0);  // exit program when connection is lost 
         return; 
        } 
       } 
      } 
     }).start(); 
    } 
} 

客戶端代碼:

import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 

import java.net.Socket; 

public class Client { 
    private  Chat   ch  = null; 
    private  Socket   s  = null; 
    private  BufferedReader in  = null; 
    private  BufferedWriter out  = null; 

    public Client() { 
     try { 
      s = new Socket("localHost", 1792); 
      in = new BufferedReader(new InputStreamReader(s.getInputStream())); 
      out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
      ch = new Chat("Client", out); 
     } catch (IOException ioe) { 

     } 

     new Thread(new Runnable() { 
      public void run() { 
       while (true) { 
        try { 
         String line = in.readLine(); 
         ch.showString(line); 
        } catch (IOException e) { 
         System.exit(0);  // exit program when connection is lost 
         return; 
        } 
       } 
      } 
     }).start(); 
    } 
} 

聊天(GUI)代碼:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Insets; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JFrame; 
import javax.swing.JTextField; 
import javax.swing.JButton; 
import javax.swing.JPanel; 
import javax.swing.JLabel; 

import java.io.BufferedWriter; 
import java.io.IOException; 

public class Chat implements ActionListener { 
    protected JFrame   fr; 
    private  JPanel   p; 
    private  JTextField  tf; 
    private  JButton   b; 
    private  int    lines = 20; 
    private  JLabel[]  l  = new JLabel[lines]; 
    private  String   title = ""; 
    private  BufferedWriter out; 

    public Chat(String name, BufferedWriter bw) { 
     title = name; 
     out = bw; 

     fr = new JFrame(title); 
     fr.setLayout(new BorderLayout()); 
     fr.setDefaultCloseOperation(fr.EXIT_ON_CLOSE); 
     fr.setSize(400, 475); 
     fr.setLocationRelativeTo(null); 
     fr.setResizable(false); 
     fr.setVisible(true); 

     Insets in = fr.getInsets(); 
     int width = fr.getWidth() - in.left - in.right; 
     int height = fr.getHeight() - in.top - in.bottom; 

     p = new JPanel(); 
     p.setLayout(null); 
     p.setBackground(Color.WHITE); 
     fr.add(p, BorderLayout.CENTER); 

     tf = new JTextField(); 
     tf.setHorizontalAlignment(tf.LEFT); 
     tf.addActionListener(this); 
     tf.setBounds(0, 400, 300, height-400); 
     p.add(tf); 

     b = new JButton("Send"); 
     b.setBounds(300, 400, width-300, height-400); 
     b.addActionListener(this); 
     p.add(b); 

     p.validate(); 
     fr.validate(); 

     p.repaint(); 
     fr.repaint(); 

     for(int i=0;i<lines;i++) { 
      l[i] = new JLabel(""); 
      l[i].setHorizontalAlignment(l[i].LEFT); 
      l[i].setBounds(0, 400*i/lines, 500, 400/lines); 
      p.add(l[i]); 
     } 
    } 

    public void showString(String text) { 
     if (text.equals("")) return; 
     for(int i=0;i<lines-1;i++) { 
      l[i].setText(l[i+1].getText()); 
     } 
     l[lines-1].setText(text); 
    } 

    public void actionPerformed(ActionEvent ae) { 
     String text = tf.getText(); 
     try { 
      showString(text); 
      out.write(text); 
      out.flush(); 
      tf.setText(""); 
     } catch (IOException ioe) { 

     } 
    } 
} 
+0

你能指定什麼不起作用嗎? – CuriousMind 2014-10-26 16:15:56

+0

程序停在「in.readLine()」方法,我不知道爲什麼。 – Checker 2014-10-26 16:20:25

+0

您應該首先了解代碼,然後將其粘貼到此處,並正確解釋什麼是工作,哪些不是。 – SMA 2014-10-26 16:24:58

回答

1

readline的()函數等待一行的末尾。 在您的聊天課程中,您永遠不會在寫入輸出流的過程中讓它結束行。因此,服務器和客戶端都會在in.readLine()中等待行尾字符,以便完成單行讀取。 您需要在寫入輸出流的每一行後給它一個行尾字符。只有沖洗它是不夠的。

所以只需在您的Chat類中修改此部分。

舊代碼

 out.write(text); 
     out.flush(); 

新代碼

 out.write(text); 
     out.write('\n'); 
     out.flush(); 

其餘全部代碼的工作精絕。祝你好運!