天天看点

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();
                }
            }
        }

    }

}