java套接字编程实现聊天室

使用Java套接字编程来实现一个简单的聊天室,它可以支持至少两个用户(即客户端)之间的聊天。服务器程序正在等待来自客户端程序的连接。当客户端连接到服务器时,服务器会发送一条“新朋友”消息,以通知以前已经连接到服务器的另一个客户端。然后,可以通过服务器完成两个客户端之间的通信。您可以选择TCP或UDP来实现这些程序。
您应该使用PSFTP将服务器/客户端程序(即本地文件)上传到一个ip地址
您应该使用putty来编译和运行服务器程序。
您应该使用PSFTP或Java编辑器(例如,Netbeans或eclipse)来编译和运行您的客户端程序。


package java3.T16;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/*
 * 用UDP技术实现简单聊天软件
 * */
import javax.swing.JTextField;
import javax.swing.JTextPane;
public class UdpChat extends JFrame implements ActionListener,Runnable{
    
    /*
     * 关键参数
     *     1.自己的IP及端口,
     *     2.对方的IP及端口
     *     3.启动线程的按钮
     *     4.发送信息的按钮
     *     5.聊天内容的文本区域框
     * 
     * */
    JTextField txtSelfAddr,txtSelfPort,txtOtherAddr,txtOtherPort;
    JButton btnStart,btnSend,btnClose;
    //发送信息及接收信息的文本区域框
    JTextPane txtChatMsg,txtReceMsg;
    
    //数据报Socket;
    DatagramSocket socket;
    
    public UdpChat() {
        super("用UDP技术实现简单聊天软件");
        
        //自己的IP
        JLabel lblSelfAddr = new JLabel("自己IP:");
        txtSelfAddr = new JTextField("127.0.0.1",8);
        
        //自己的端口
        JLabel lblSelfPort = new JLabel("自己端口:");
        txtSelfPort = new JTextField("8888",5);
        //对方IP
        JLabel lblOtherAddr = new JLabel("自己端口:");
        txtOtherAddr = new JTextField("127.0.0.1",8);
        //对方端口
        JLabel lblOtherPort = new JLabel("对方端口:");
        txtOtherPort = new JTextField("8889",5);
        //启动线程的按钮
        btnStart = new JButton("启动接收线程");
        //发送信息
        btnSend = new JButton("发送");
        //关闭程序
        btnClose = new JButton("关闭");
        
        //注册按钮事件
        btnStart.addActionListener(this);
        btnSend.addActionListener(this);
        btnClose.addActionListener(this);
        
        
        JPanel northPane = new JPanel(new FlowLayout());
        northPane.add(lblSelfAddr);
        northPane.add(txtSelfAddr);
        northPane.add(lblSelfPort);
        northPane.add(txtSelfPort);
        northPane.add(lblOtherAddr);
        northPane.add(txtOtherAddr);
        northPane.add(lblOtherPort);
        northPane.add(txtOtherPort);
        northPane.add(btnStart);
        add(northPane,BorderLayout.NORTH);
        
        //聊天内容文本框放在中间
        txtChatMsg = new JTextPane();
        txtReceMsg = new JTextPane();
        JPanel centerPane = new JPanel(new GridLayout(2,1,5,10));
        centerPane.add(txtReceMsg);
        centerPane.add(txtChatMsg);
        add(centerPane);
        //发送按钮,关闭按钮放在底部右边
        JPanel southPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        southPane.add(btnSend);
        southPane.add(btnClose);
        add(southPane,BorderLayout.SOUTH);
        setSize(800,500);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        
    }
    //启动接收线程
    
    
    public static void main(String[] args) {
        UdpChat chat = new UdpChat();
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == btnClose) {
            System.exit(1);
        }else if(e.getSource() == btnStart) {
            //启动线程
            Thread thread = new Thread(this);
            thread.start();
            //把按钮状态设置为不可用状态
            btnStart.setEnabled(false);
        }else if(e.getSource() == btnSend) {
            //获取对方的IP及端口
            String host = txtOtherAddr.getText();
            int port = Integer.parseInt(txtOtherPort.getText());
            
            InetAddress netAddr;
            try {
                netAddr = InetAddress.getByName(host);
                //创建发送信息的Socket
                DatagramSocket socket = new DatagramSocket();
                //获取发送文本框的内容
                String msg = txtChatMsg.getText();
                //创建数据报
                byte b[] = msg.getBytes();
                DatagramPacket p = new DatagramPacket(b, b.length,netAddr,port);
                //发送
                socket.send(p);
                System.out.println("发送成功...");
                //获取接收文本框的内容,同时加入发送的内容
                msg = txtReceMsg.getText() + "\n发给对方的信息:" + msg; 
                txtReceMsg.setText(msg);
                //清空发送框的内容
                txtChatMsg.setText("");
                //关闭
                socket.close();
                
            } catch (UnknownHostException e1) {
                e1.printStackTrace();
            } catch (SocketException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            
        }
        
    }


    @Override
    public void run() {
        //监听是否有信息需要接收
        //获取自己端口
        int port = Integer.parseInt(txtSelfPort.getText());
        byte b[] = new byte[2048];
        int len=0;
        try {
            //创建UDP套接字(DatagramSocket)
            socket = new DatagramSocket(port);
            //接收信息的DatagramPacket对象
            DatagramPacket p = new DatagramPacket(b, b.length);
            while(true) {
                //接收信息
                socket.receive(p);
                //把接收的数据转换为字符串
                len = p.getLength();
                String msg = new String(b,0,len);
                msg = txtReceMsg.getText() + "\n接收对方的信息:" + msg; 
                txtReceMsg.setText(msg);
                
            }
            
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }        
    }

}