这是我以前编的一个类似于QQ的网络聊天机,仅仅实现了消息聊天这个简单的功能,其他很多功能还没有实现,这个程序只能作为练笔,还不能应用于实际当中,程序编写主要参考尚学堂视频教程,里面还有一个异常我不会处理,想请教各位,请各位多多指点,多多指教!
本程序有两个程序文件,一个是客户端程序ChatClient.java,一个是服务器端程序ChatServer.java,实现服务器功能。
源程序:
客户端程序:
ChatClient.java
package org.standlww.Application.Project.Chat;
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*;
public class ChatClient {
private JFrame jFrame = null; // @jve:decl-index=0:visual-constraint="241,73" private JPanel jContentPane = null; private JTextArea jTextArea = null; private JButton jButton = null; private JButton jButton1 = null; private JTextArea jTextArea1 = null; private Socket s=null; // @jve:decl-index=0: private InputStream inStream=null; // @jve:decl-index=0: private OutputStream outStream=null; private Scanner in=null; private PrintWriter out=null; private String message=null; private String receivedMessage=null; private Thread receiveRunnable=null; private boolean bConnected=false; /** * This method initializes jFrame * * @return javax.swing.JFrame */ private JFrame getJFrame() { if (jFrame == null) { jFrame = new JFrame(); jFrame.setTitle("网络聊天鸡"); jFrame.setBounds(new Rectangle(301, 166, 441, 436)); jFrame.setContentPane(getJContentPane()); jFrame.setVisible(true); jFrame.addWindowListener(new WindowAdapter(){
@Override /*在exit(0)退出客户端程序前,应先调用disconnect()方法,先做把Socket inStream等关闭和回收的处理, 但目前调用disconnect()方法会造成客户端程序无法退出,原因是ReceiveRunnable类中的run()方法中的in.next()为阻塞型, 无法使线程退出,到目前为止还不知道怎么使这个线程退出,期待解决!*/ public void windowClosing(WindowEvent event) { //disconnect(); System.exit(0); //super.windowClosing(e); } }); } return jFrame; }
/** * This method initializes jContentPane * * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(null); jContentPane.add(getJTextArea(), null); jContentPane.add(getJButton(), null); jContentPane.add(getJButton1(), null); jContentPane.add(getJTextArea1(), null); } return jContentPane; }
/** * This method initializes jTextArea * * @return javax.swing.JTextArea */ private JTextArea getJTextArea() { if (jTextArea == null) { jTextArea = new JTextArea(); jTextArea.setBounds(new Rectangle(8, 9, 417, 263)); jTextArea.setEditable(false); //new JScrollPane(jTextArea); jTextArea.setText("聊天窗口"); } return jTextArea; }
/** * This method initializes jTextArea1 * * @return javax.swing.JTextArea */ private JTextArea getJTextArea1() { if (jTextArea1 == null) { jTextArea1 = new JTextArea(); jTextArea1.setBounds(new Rectangle(11, 282, 412, 89)); jTextArea1.setLineWrap(true); new JScrollPane(jTextArea1);//.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); } return jTextArea1; } /** * This method initializes jButton1 * * @return javax.swing.JButton */ private JButton getJButton1() { if (jButton1 == null) { jButton1 = new JButton(); jButton1.setBounds(new Rectangle(321, 376, 82, 21)); jButton1.setText("发送"); jButton1.addActionListener(new SendMessageListener()); } return jButton1; } /** * This method initializes jButton * * @return javax.swing.JButton */ private JButton getJButton() { if (jButton == null) { jButton = new JButton(); jButton.setBounds(new Rectangle(227, 376, 82, 21)); jButton.setText("关闭"); jButton.addActionListener(new CloseAndExitListener()); } return jButton; }
ChatClient(){ lanchFrame(); connect(); } private void connect() { try { s=new Socket("127.0.0.1",8888); bConnected=true; System.out.println("Connected!"); inStream=s.getInputStream(); outStream=s.getOutputStream(); in=new Scanner(inStream); out=new PrintWriter(outStream,true); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } receiveRunnable=new Thread(new ReceiveRunnable()); receiveRunnable.start(); } private void disconnect(){ /*try{ bConnected=false; receiveRunnable.join(); }catch(InterruptedException e){ e.printStackTrace(); }finally{*/ try{ if(out==null){ out.close(); out=null; } if(in!=null){ in.close(); in=null; } if(outStream==null){ outStream.close(); outStream=null; } if(inStream!=null){ inStream.close(); inStream=null; } if(s==null){ s.close(); s=null; } } catch(IOException e){ e.printStackTrace(); } // } } private void lanchFrame(){ getJFrame(); }
private class CloseAndExitListener implements ActionListener{
public void actionPerformed(ActionEvent event) { //disconnect(); System.exit(0); } } private class SendMessageListener implements ActionListener{
public void actionPerformed(ActionEvent event) { //try{ message=jTextArea1.getText().trim(); if(message.equals("")) System.out.println("不能发送空白内容!");//这里应该是显示一消息:不能发送空白内容 else{ jTextArea.append("/n");//之前得先换行 jTextArea.append(message); jTextArea1.setText(""); out.println(message); } //}finally{ //s.close(); //} } }
private class ReceiveRunnable implements Runnable{
public void run() { while(bConnected&&in.hasNextLine()){ receivedMessage=in.nextLine(); jTextArea.append("/n"); jTextArea.append(receivedMessage); } } }
public static void main(String[] args) { new ChatClient();
}
}
服务器端程序:
ChatServer.java
package org.standlww.Application.Project.Chat;
import java.net.*; import java.io.*; import java.util.*;
public class ChatServer {
private ServerSocket s=null; private Socket incoming=null; boolean started=false; private ArrayList<Client> Clients=new ArrayList<Client>(); private Client client=null; public static void main(String[] args) { new ChatServer().start(); } void start(){ try{ s=new ServerSocket(8888); System.out.println("服务器已经启动!"); started=true; }catch(BindException e){ System.out.println("服务器已经启动,端口使用中..."); System.out.println("请关闭相关程序,重新启动服务器!"); System.exit(0); }catch(IOException e){ e.printStackTrace(); } try{ while(started){ incoming=s.accept(); client=new Client(incoming); Clients.add(client); new Thread(client).start(); System.out.println("a Client connected!"); } }catch(EOFException e){ System.out.println("Client Closed!"); } catch (IOException e) { e.printStackTrace(); }finally{ try{ if(s!=null){ s.close(); s=null; } }catch(IOException e){ e.printStackTrace(); } } }
private class Client implements Runnable{
private Socket incoming=null; private InputStream inStream=null; private OutputStream outStream=null; private Scanner in=null; private PrintWriter out=null; private String message=null; private boolean bConnected=false; Client(Socket incoming){ this.incoming=incoming; bConnected=true; try { inStream=incoming.getInputStream(); outStream = incoming.getOutputStream(); in=new Scanner(inStream); out=new PrintWriter(outStream,true); } catch (IOException e) { e.printStackTrace(); } } /*这个函数需要改进,当客户端程序有一方退出时会抛出NullPointerException,到目前为止还不知道怎么处理这个异常,期待解决!*/ void sendMessage(String message) { out.println(message); } public void run() { //try{ while(bConnected==true&&in.hasNextLine()){ message=in.nextLine(); for(int i=0;i<Clients.size();i++){ Client c=Clients.get(i); if(c!=this) c.sendMessage(message); } } //} //finally{ try{ if(in!=null){ in.close(); in=null; } if(out!=null){ out.close(); out=null; } if(inStream!=null){ inStream.close(); inStream=null; } if(outStream!=null){ outStream.close(); outStream=null; } if(incoming!=null){ incoming.close(); incoming=null; } }catch(IOException e){ e.printStackTrace(); } // } } }
}