天天看點

JAVA--簡易聊天室程式

寫在前面:

       網絡程式設計是指編寫與其他計算機進行通信的程式,java已經将網絡程式所需要的東西封裝成不同的類。隻要建立這些類的對象,進行執行個體化,使用相應的方法,即可實作功能。

本執行個體使用的類(swing部分不進行列舉):

  • Socket
public Socket(InetAddress address,int port) throws IOException
public Socket(String host,int port) throws UnknowHostException,IOException
public Socket(InetAddress address,int port,InetAddress localAddr,int localport) throws IOException

public InetAddress getInetAddress()//傳回套接字連接配接的主機位址
public InetAddress getLocalAddress()//傳回套接字綁定的本地位址
public InputStream getInputStream()throws IOException//獲得該套接字的輸入流
public int getLocalPort()//傳回套接字綁定的本地端口
public int getPort()//傳回套接字連接配接的遠端端口
public OutputStream getOutputSteam()throws IOException//傳回該套接字的輸出流
public int getSoTimeout()throws SocketException//傳回該套接字最長等待時間


public void setSoTimeout(int timeout)throws SocketException//設定該套接字最長等待時間

public void shutdownInput()throws IOException//關閉輸入流
public void shutdownOutput()throws IOException//關閉輸出流

public void close()throws IOException//關閉套接字
           
  • DataOutputStream
public final void write(byte[] w, int off, int len)throws IOException
//将指定位元組數組中從偏移量 off 開始的 len 個位元組寫入此位元組數組輸出流。
public final int write(byte [] b)throws IOException
//将指定的位元組寫入此位元組數組輸出流。
public final void writeBooolean()throws IOException,
public final void writeByte()throws IOException,
public final void writeShort()throws IOException,
public final void writeInt()throws IOException
//這些方法将指定的基本資料類型以位元組的方式寫入到輸出流。
public void flush()throws IOException
//重新整理此輸出流并強制寫出所有緩沖的輸出位元組。
public final void writeBytes(String s) throws IOException
//将字元串以位元組序列寫入到底層的輸出流,字元串中每個字元都按順序寫入,并丢棄其高八位。
           
  • DataInputStream
int read(byte[] b) //從包含的輸入流中讀取一定數量的位元組,并将它們存儲到緩沖區數組 b 中。

 int read(byte[] b, int off, int len) 
//從包含的輸入流中将最多 len 個位元組讀入一個 byte 數組中。

 boolean readBoolean() 
//參見 DataInput 的 readBoolean 方法的正常協定。

 byte readByte() 
 //參見 DataInput 的 readByte 方法的正常協定。

 char readChar() 
//參見 DataInput 的 readChar 方法的正常協定。

 double readDouble() 
//參見 DataInput 的 readDouble 方法的正常協定。

 float readFloat() 
//參見 DataInput 的 readFloat 方法的正常協定。

 void readFully(byte[] b) 
//參見 DataInput 的 readFully 方法的正常協定。

 void readFully(byte[] b, int off, int len) 
//參見 DataInput 的 readFully 方法的正常協定。

 int readInt() 
//參見 DataInput 的 readInt 方法的正常協定。

 long readLong() 
//參見 DataInput 的 readLong 方法的正常協定。

 short readShort() 
//參見 DataInput 的 readShort 方法的正常協定。

 int readUnsignedByte() 
//參見 DataInput 的 readUnsignedByte 方法的正常協定。

 int readUnsignedShort() 
//參見 DataInput 的 readUnsignedShort 方法的正常協定。

 String readUTF() 
//參見 DataInput 的 readUTF 方法的正常協定。

static String readUTF(DataInput in) 
//從流 in 中讀取用 UTF-8 修改版格式編碼的 Unicode 字元格式的字元串;然後以 String 形式傳回此字元串。

 int skipBytes(int n) 
//參見 DataInput 的 skipBytes 方法的正常協定。
           
  • ServerSocket
public ServerSocket(int port) throws IOException
public ServerSocket(int port,int backlog) throws IOException
public ServerSocket(int port,int backlog,InetAddress bindAddr) throws IOException


public Socket accept() throws IOException//監聽并接受用戶端Socket連接配接
public InetAddress getInetAddress()//傳回伺服器套接字的本地位址

public int getLocalPort()//傳回套接字監聽的端口



public int getSoTimeout()throws SocketException//傳回該套接字最長等待時間


public void setSoTimeout(int timeout)throws SocketException//設定該套接字最長等待時間   

public void close()throws IOException//關閉套接字
           

詳細請查閱線上文檔-jdk-zh

用戶端代碼執行個體:

/**
 * 
 */
package test網絡通信.聊天室;

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import javax.swing.*;

public class TCPClient extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = L;
    TextArea taContent = new TextArea();
    JTextField tfTxt = new JTextField();

    JButton send = new JButton("發送");
    JButton connect = new JButton("連接配接");
    JButton clear = new JButton("清空");

    boolean live = false;
    JPanel p1 = new JPanel();
    JPanel p2 = new JPanel();

    Socket s = null;
    DataOutputStream dos = null;
    DataInputStream dis = null;

    boolean bConnected = false;//連結狀态

    Thread t = new Thread(new RecToServer());//從伺服器讀取資料

    public void launchFrame() {

        taContent.setEditable(false);

        p2.setLayout(new FlowLayout(FlowLayout.CENTER, , ));
        p2.add(send);
        p2.add(connect);
        p2.add(clear);

        Container con = this.getContentPane();

        con.add(taContent, "North");
        con.add(tfTxt, "Center");
        con.add(p2, "South");

        this.setSize(, );
        this.setLocation(, );
        this.setTitle("Chat Client");

        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        connect.addActionListener(new Connect());
        send.addActionListener(new SendMsg());
        clear.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                taContent.setText("");
            }
        });
    }

    public void connectToServer() {//連接配接伺服器
        try {

            s = new Socket("127.0.0.1", );
            dos = new DataOutputStream(s.getOutputStream());
            dis = new DataInputStream(s.getInputStream());

            bConnected = true;

        } catch (BindException e) {
            System.out.println("找不到指定的伺服器");
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void disConnect() {
        try {
            if (s != null) {
                s.close();
            }

            if (dos != null) {
                dos.close();
            }
            if (dis != null) {
                dis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        TCPClient tc = new TCPClient();
        tc.launchFrame();
    }

    private class Connect implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (e.getActionCommand() == "連接配接") {

                connectToServer();
                try {
                    t.start();
                } catch (IllegalThreadStateException ex) {

                }

                connect.setText("斷開連接配接");

            } else if (e.getActionCommand() == "斷開連接配接") {
                disConnect();
                connect.setText("連接配接");
            }

        }
    }

    private class SendMsg implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            if (connect.getActionCommand() == "連接配接") {
                JOptionPane.showMessageDialog(TCPClient.this,
                        "沒有找到指定的伺服器", "錯誤提示", );
            } else {
                String str = tfTxt.getText();
                tfTxt.setText("");

                try {
                    dos.writeUTF(str);//向伺服器端發資料
                    dos.flush();
                } catch (SocketException ex) {
                    System.out.println("沒有找到指定的伺服器");
                    JOptionPane.showMessageDialog(TCPClient.this,
                            "沒有找到指定的伺服器", "錯誤提示", );
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }

    private class RecToServer implements Runnable {
        public void run() {
            try {
                while (bConnected) {//連結的時候操作
                    String str = dis.readUTF();//從伺服器端讀取資料
                    // System.out.println(str);

                    taContent.append(str + "\n");//添加到文本顯示域
                }
            } catch (SocketException e) {
                System.out.println("伺服器已關閉");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
           

伺服器端代碼:

/**
 * 
 */
package test網絡通信.聊天室;
//伺服器端程式
import java.awt.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.List;

import javax.swing.*;

public class TCPServer extends JFrame {
    /**
     * 
     */
    private static final long serialVersionUID = L;
    private ServerSocket ss = null;
    private boolean bStart = false;

    private JTextArea taContent = new JTextArea();

    private int index = ;

    List<Client> clients = new ArrayList<Client>();

    public void launchFrame() {
//      Container con = this.getContentPane();
        taContent.setEditable(false);

        taContent.setBackground(Color.DARK_GRAY);
        taContent.setForeground(Color.YELLOW);
        this.add(taContent);
        this.setSize(, );
        this.setLocation(, );
        this.setTitle("TCP Server");
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        tcpMonitor();
    }

    public void tcpMonitor() {
        try {
            ss = new ServerSocket();
            bStart = true;
        } catch (IOException e) {

            e.printStackTrace();
        }

        try {
            while (bStart) {
                index++;
                Socket s = ss.accept();
                Client c = new Client(s);
                clients.add(c);

                taContent.append(s.getInetAddress().getHostAddress()
                        + " connected " + index + " clients\n");
                new Thread(c).start();

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ss.close();
            } catch (IOException e) {

                e.printStackTrace();
            }
        }

    }

    public static void main(String args[]) {
        TCPServer ts = new TCPServer();
        ts.launchFrame();
    }

    private class Client implements Runnable {
        DataInputStream dis = null;
        DataOutputStream dos = null;

        Socket s = null;
        boolean bStart = false;

        Client(Socket s) {
            this.s = s;
            try {
                dis = new DataInputStream(s.getInputStream());
                dos = new DataOutputStream(s.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }

            bStart = true;
        }

        public void sendToEveryClient(String str) {
            try {
                dos.writeUTF(str);
                dos.flush();

            } catch (IOException e) {
                index--;
                clients.remove(this);
                taContent.append(s.getInetAddress().getHostAddress()
                        + " exited " + index + " clients\n");
                System.out.println("對方退出了!我從List裡面去掉了!");
            }
        }

        public void run() {
            try {
                while (bStart) {
                    String str = dis.readUTF();
                    System.out.println(str);
                    for (int i = ; i < clients.size(); i++) {
                        Client c = clients.get(i);
                        c.sendToEveryClient(str);
                    }
                }
            } catch (EOFException e) {
                clients.remove(this);
                taContent.append(s.getInetAddress().getHostAddress()
                        + " exited " + clients.size() + " clients\n");
                System.out.println("client closed");
            } catch (SocketException e) {
                System.out.println("client closed");
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (s != null)
                        s.close();
                    if (dis != null)
                        dis.close();
                    if (dos != null)
                        dos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}