《计算机网络》课程设计报告设计题目:聊天室同组人姓名:王巍瑾马志超周旭同组人学号:***********2015151510420151515138专业班级:计科153指导教师:***日期:2017年6月12日—16日一、题目意义和需求分析1.题目意义即时通讯或在线聊天是目前Internet上最为流行的通讯方式,用户之间通过文字传输信息。
这是一种可以让使用者在网络上建立私人聊天室的实时通讯服务。
除了简单的文字信息,使用者之间还可以互相发送文件、文档、音乐、视频等文件。
只要与服务器链接,无论对方在天涯海角,双方隔得多远都没有问题。
消息的实时更新,拉近了我们相知的桥梁,文件的相互传输,使同事之间办公更方便快捷。
2.需求分析a.注册当选择注册时,创建一个File文件类,载入“user.txt”,判断用户名是否已经存在,用户名有效后写入“user.txt”。
b.登录去“user.txt”读取用户数据,验证用户名是否存在,验证用户密码是否正确,如果以上验证全部正确,返回客户端信息,提示登陆成功进入聊天界面。
c.聊天所有已登录的用户的名称都会在列表中显示,然后就可以选择其中一个或多个发起聊天。
接收用户聊天信息,当用户发送聊天信息时,服务端将会收到客户端用Socket传输过来的聊天信息对象,然后将其转换为Message对象,返回聊天信息,然后系统从Message中提取消息类型,再根据类型将消息转化后通过Socket转发到相应的用户。
d.文件传输在聊天的基础上增加了一个文件传输功能。
同事之间办公难免有一些资料的来往,在登录列表中选择一个用户或多个用户发送文件,等对方确认接收后即可建立连接进行文件传输。
二、设计说明聊天室总体分为三个模块,主要包括注册登录,聊天模块,文件传输模块。
系统运行在java环境中,要求java环境为JDK 1.8+;设计中的重点是通过Java中的ServerSocket搭建TCP服务器,通过在客户端创建Socket套接字连接服务器,然后通过ObjectOutputStream来发送Message(数据消息的封装类)对象让服务器接受。
通过线程来存储来存储用户的Socket连接状态,接受并处理用户发过来的信息,返回处理信息。
客户机也通过线程来接受服务器的处理数据做出响应。
设计的难点是文件的传输,首先通过原有的服务器获得目标客户机的IP地址和端口,然后在客户机上建立服务器,通过要发送的文件的客户机连接接受文件的客户机用DataInputStream 和DataOutputStream 来推送到输入、输出流。
然1.2. 流程图四、程序源代码及注释public ChatRoom(String u_name, Socket client) {// 赋值name = u_name;clientSocket = client;onlines = new Vector();setTitle(name);setResizable(false);setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);setBounds(200, 100, 688, 510);contentPane = new JPanel();setContentPane(contentPane);contentPane.setLayout(null);// 聊天信息显示区域JScrollPane scrollPane = new JScrollPane();scrollPane.setBounds(10, 10, 410, 300);getContentPane().add(scrollPane);textArea = new JTextArea();textArea.setEditable(false);textArea.setLineWrap(true);//激活自动换行功能textArea.setWrapStyleWord(true);//激活断行不断字功能textArea.setFont(new Font("sdf", Font.BOLD, 13));scrollPane.setViewportView(textArea);// 打字区域JScrollPane scrollPane_1 = new JScrollPane(); scrollPane_1.setBounds(10, 347, 411, 97); getContentPane().add(scrollPane_1);final JTextArea textArea_1 = new JTextArea();textArea_1.setLineWrap(true);//激活自动换行功能textArea_1.setWrapStyleWord(true);//激活断行不断字功能scrollPane_1.setViewportView(textArea_1);// 关闭按钮final JButton btnNewButton = new JButton("关闭"); btnNewButton.setBounds(214, 448, 60, 30); getContentPane().add(btnNewButton);// 发送按钮JButton btnNewButton_1 = new JButton("发送"); btnNewButton_1.setBounds(313, 448, 60, 30); getRootPane().setDefaultButton(btnNewButton_1); getContentPane().add(btnNewButton_1);// 在线客户列表listmodel = new UUListModel(onlines) ;list = new JList(listmodel);list.setCellRenderer(new CellRenderer());list.setOpaque(false);Border etch = BorderFactory.createEtchedBorder();list.setBorder(BorderFactory.createTitledBorder(etch, "<"+u_name+">"+"在线用户:", TitledBorder.LEADING, TitledBorder.TOP, new Font("sdf", Font.ITALIC, 20), Color.black));JScrollPane scrollPane_2 = new JScrollPane(list);scrollPane_2.setBounds(430, 10, 245, 375);scrollPane_2.setOpaque(false);scrollPane_2.getViewport().setOpaque(false);getContentPane().add(scrollPane_2);// 文件传输栏progressBar = new JProgressBar();progressBar.setBounds(430, 390, 245, 15);progressBar.setMinimum(1);progressBar.setMaximum(100);getContentPane().add(progressBar);// 文件传输提示lblNewLabel = new JLabel("文件传输信息栏:");lblNewLabel.setFont(new Font("SimSun", Font.PLAIN, 12));lblNewLabel.setBackground(Color.WHITE);lblNewLabel.setBounds(430, 410, 245, 15);getContentPane().add(lblNewLabel);try {oos = new ObjectOutputStream(clientSocket.getOutputStream());// 记录上线客户的信息,并发送给服务器Message toMsg = new Message();toMsg.setType(0);toMsg.setName(name);toMsg.setTimer(getTimer());oos.writeObject(toMsg);oos.flush();// 启动客户接收线程CThread = new ClientInputThread();CThread.start();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 发送按钮btnNewButton_1.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {String info = textArea_1.getText();List to = list.getSelectedValuesList();if (to.size() < 1) {JOptionPane.showMessageDialog(getContentPane(), "请选择聊天对象");return;}if (to.toString().contains(name+"(我)")) {JOptionPane.showMessageDialog(getContentPane(), "不能向自己发送信息");return;}if (info.equals("")) {JOptionPane.showMessageDialog(getContentPane(), "不能发送空信息");return;}Message toMsg = new Message();toMsg.setType(1);toMsg.setName(name);String time = getTimer();toMsg.setTimer(time);toMsg.setInfo(info);HashSet set = new HashSet();set.addAll(to);toMsg.setClients(set);// 自己发的内容也要现实在自己的屏幕上面textArea.append(time + " 我对" + to + "说:\r\n" + info + "\r\n");sendMessage(toMsg);textArea_1.setText(null);textArea_1.requestFocus();}});// 关闭按钮btnNewButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {if(isSendFile || isReceiveFile){JOptionPane.showMessageDialog(contentPane,"正在传输文件中,您不能离开...","Error Message", JOptionPane.ERROR_MESSAGE);}else{btnNewButton.setEnabled(false);Message toMsg = new Message();toMsg.setType(-1);toMsg.setName(name);toMsg.setTimer(getTimer());sendMessage(toMsg);b = false;}}});// 离开this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {// TODO Auto-generated method stubif(isSendFile || isReceiveFile){JOptionPane.showMessageDialog(contentPane,"正在传输文件中,您不能离开...","Error Message", JOptionPane.ERROR_MESSAGE);}else{int result = JOptionPane.showConfirmDialog(getContentPane(),"您确定要离开聊天室");if (result == 0) {Message toMsg = new Message();toMsg.setType(-1);toMsg.setName(name);toMsg.setTimer(getTimer());sendMessage(toMsg);// CThread.interrupt();b = false;}}}});// 列表监听list.addMouseListener(new MouseAdapter() {public void mouseClicked(MouseEvent e) {List to = list.getSelectedValuesList();if (e.getClickCount() == 2) {if (to.toString().contains(name+"(我)")) {JOptionPane.showMessageDialog (getContentPane(), "不能向自己发送文件");return;}// 双击打开文件文件选择框FileChoose chooser = new FileChoose();chooser.setDialogTitle("选择文件框"); // 标题哦...chooser.showDialog(getContentPane(), "选择"); // 这是按钮的名字..// 判定是否选择了文件if (chooser.getSelectedFile() != null) {// 获取路径filePath = chooser.getSelectedFile().getPath();File file = new File(filePath);// 文件为空if (file.length() == 0) {JOptionPane.showMessageDialog (getContentPane(),filePath + "文件为空,不允许发送.");return;}Message toMsg = new Message();toMsg.setType(2);// 请求发送文件toMsg.setSize(new Long(file.length()).intValue());toMsg .setName(name);toMsg.setTimer(getTimer());toMsg.setFileName(file.getName()); // 记录文件的名称toMsg.setInfo("请求发送文件");// 判断要发送给谁HashSet<String> set = new HashSet<String>();set.addAll(list.getSelectedValuesList());toMsg.setClients(set);sendMessage(toMsg);}}}});}五、实验数据、结果分析1.开启服务器服务器用来将用户发送的信息发送到指定用户,所以程序执行之前服务器一定要开启。