java课程作业-点对点聊天软件

1.首先分享界面效果

有服务端用户显示界面,客户端好友列表界面。

还有客户端的聊天界面。

2.主要功能:好友管理(连接数据库实现),点对点聊天,密码管理(文件实现),好友上线自动提示,表情和文件。

3.连接的数据库是phpstudy安装的mysql,表结构如下。(为了方便只能实现添加5位好友)

4.源代码目录结构如下,分为client和server两部分,都由main类启动。image和receive-file用于保存接收和发送的文件或表情(即图片),其中服务端的user.txt保存用户密码信息,联合数据库实现登录功能。

5.这里贴上客户端和服务端的main类代码。

package src.client;

import java.net.*;
import java.io.*;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class ClientMain {
    static Socket socket = null;//连接服务器
    static DataInputStream inputFromServer = null;
    static DataOutputStream outputToServer = null;
    static Thread receiveRequestThread;

    //好友列表
    static String[] columnNames = { "好友昵称", "在线状态" };
    static Object[][] rowData = {};
    static DefaultTableModel defaultModel = new DefaultTableModel(rowData, columnNames);

    public static void main(String[] args){
        new ClientMain();
    }

    public ClientMain(){
        String text[] = inputText();//登录界面,获取输入信息

        linkServer(text[0], text[1], Integer.parseInt(text[2]), text[3]);// 连接服务器

        new WorkWindow(text[0]);//显示好友列表

        receiveRequestThread = new Thread(new WorkReceive());//创建接收请求的线程
        receiveRequestThread.start();       
    }
     
    //登录界面
    public String[] inputText(){
        //初始化文本输入
        JTextField textName = new JTextField(10);
        textName.setText("张三");
        JPasswordField textPassword = new JPasswordField(10);
        textPassword.setText("aS1234567");
        JTextField textAddress = new JTextField(16);
        textAddress.setText("127.0.0.1");
        JTextField textPort = new JTextField(5);
        textPort.setText("9001");

        //接收输入
        String text[] = new String[4];
        boolean goon = true;
        while(goon){

            //登录窗口
            int a = JOptionPane.showConfirmDialog(null,
                new Object[] { "请输入你的昵称(新用户将自动注册)", textName, "请输入你的登录密码", textPassword, 
                "请输入你要连接的地址: ", textAddress, "请输入端口号: ", textPort},
                "登录",
				JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);

            if(a == JOptionPane.OK_OPTION){ //点击确认
                text[0] = textName.getText();
                text[1] = textAddress.getText().trim();
                text[2] = textPort.getText().trim();
                text[3] = new String(textPassword.getPassword());

                //检验输入
                if (text[0].length() < 1 || text[0].length() > 10) {
                    JOptionPane.showMessageDialog(null, "昵称长度应为1-10个字符", "输入错误", JOptionPane.ERROR_MESSAGE);
                    continue; 
                }
                if(!text[3].matches("^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=\\S+$).{8,}$")) {
                    JOptionPane.showMessageDialog(null, "密码必须包含至少一个小写字母、一个大写字母、一个数字,并且长度至少为8位", "输入错误", JOptionPane.ERROR_MESSAGE);
                    continue; 
                }
                if(Integer.parseInt(text[2]) > 65535 || Integer.parseInt(text[2]) < 1024){
                    JOptionPane.showMessageDialog(null, "端口号不可用", "输入错误", JOptionPane.ERROR_MESSAGE);
                    continue;
                }
                if(!text[1].matches("(\\d{1,3}\\.){3}\\d{1,3}")) {
                    JOptionPane.showMessageDialog(null, "请输入正确的IP地址", "输入错误", JOptionPane.ERROR_MESSAGE);
                    continue; 
                }    
                goon = false;

            }else{
                System.exit(0);
            }        
        }
        return text;
    }

    // 连接服务器
	public void linkServer(String name, String ip, int port, String password) {
		try {
            socket = new Socket(ip, port);
			inputFromServer = new DataInputStream(socket.getInputStream());
            outputToServer = new DataOutputStream(socket.getOutputStream());
            outputToServer.writeUTF(name);
            outputToServer.writeUTF(password);
            outputToServer.flush();
            
		} catch (IOException e) {
			JOptionPane.showMessageDialog(null, "服务器不在线或端口错误", "连接失败", JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}

        try {
            String str = inputFromServer.readUTF();
            if(str.equals("登录失败")){//服务端检测到密码错误
            //退出程序              
            JOptionPane.showMessageDialog(null, "密码错误", "警告", JOptionPane.ERROR_MESSAGE);
            inputFromServer.close();
            outputToServer.close();
            socket.close();          
            System.exit(0);                   
            } 
            
            //接收好友列表
            int num = inputFromServer.readInt();
            String friendInfo[] = new String[num];
            for(int i=0; i<num; i++){
                friendInfo[i] = inputFromServer.readUTF();
                String state = inputFromServer.readUTF();
                Object[] row = {friendInfo[i], state};
                defaultModel.addRow(row);
            }

        } catch (Exception e) {
                e.printStackTrace();
            }
	}

}
package src.server;

import java.net.*;
import java.util.HashMap;
import java.util.Map;
import java.io.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

import javax.swing.table.DefaultTableModel;

public class ServerMain extends JFrame {

    public static int port = 9001;
    ServerSocket serverSocket = null;
    Socket socket = null;
    Thread thread;
	static Map<String, Socket> userSocketMap = new HashMap<>();

    // 界面显示客户端信息
	static String[] columnNames = { "用户名", "上线时间", "ip", "状态" };
	static Object[][] rowData = {};
	static DefaultTableModel defaultModel = new DefaultTableModel(rowData, columnNames);
	JTable table = new JTable(defaultModel);
	JScrollPane JSPanel = new JScrollPane(table);
	JPanel SPanel = new JPanel();
	

    public static void main(String[] args) {
        new ServerMain();
    }
    
    public ServerMain(){
		// 设置表格外观
		table.getTableHeader().setBackground(new Color(135, 206, 250));
		table.getTableHeader().setForeground(Color.WHITE); 
		table.setBackground(new Color(173, 216, 230));
		Font tableFont = new Font("UTF", Font.BOLD, 12); 
		table.setFont(tableFont); 
		table.getTableHeader().setFont(tableFont); 
		table.setRowHeight(35); 

        //设置窗口
        this.setTitle("CL服务器");	
		this.setBounds(50, 150, 300, 600);
		this.setResizable(false); 
		SPanel.add(JSPanel);
		this.add(SPanel, BorderLayout.SOUTH);
		this.pack();
		this.addWindowListener(new CloseSrever());
		this.setVisible(true);

		//启动服务器,开始接收客户端连接
        acceptClient();
    }

	// 监听类 处理屏幕关闭
	class CloseSrever extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
		try {
			// 通知在线的各客户端
			for (int i = 0; i < defaultModel.getRowCount(); i++) {
				if (defaultModel.getValueAt(i, 3).equals("在线")) {
					Socket socket = userSocketMap.get(defaultModel.getValueAt(i, 0));
					DataOutputStream outputToClient = new DataOutputStream(socket.getOutputStream());
					outputToClient.writeUTF("exit");
					outputToClient.flush();
				}					
			}
		
			serverSocket.close();
			System.exit(0);          
		} catch (IOException e2) {
			e2.printStackTrace();
		}
			
		}
	}
    
	//启动服务器,开始接收客户端连接
	public void acceptClient() {
        boolean goon = true;
		//打开端口
		try {
			serverSocket = new ServerSocket(port);
		} catch (IOException e1) {
			JOptionPane.showMessageDialog(null, "端口已被使用,请重新运行", "启动失败", JOptionPane.ERROR_MESSAGE);
			System.exit(0);
		}
		
        //开启监听
		try {
			while (goon) {
				socket = serverSocket.accept();
                			
				if(socket != null){			
				HandleClient hc = new HandleClient(socket); 		
				thread = new Thread(hc);
				thread.start();
				} 			
			}
		} catch (IOException e) {
			e.printStackTrace();
			goon = false;
		} 
	}
}

	

资源已绑定在上传文件中,也可以留下评论免费获取。

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值