计算机网络综合实习一对一聊天

更新时间:2024-01-20 19:56:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

青岛农业大学 理学与信息科学学院

计算机网络综合实习报告

设 计 题 目 实现一个一对一的聊天程序

学生专业班级

学生姓名(学号)

指 导 教 师

完 成 时 间

设 计 地 点

年 月 日

目 录

一.实验目的及实验环境 ..................................................... 1

1.实验目的 ............................................................ 1 2.实验环境 ............................................................ 1 二. 实验内容 ............................................................. 1

1.设计概要 ............................................................ 2 2.功能要求 ............................................................ 2 3.功能设计 ............................................................ 3

1)流程图 .......................................................... 3 2)功能实现 ........................................................ 3

四.测试数据及运行结果 .................................................... 4 五. 实验总结 ............................................................. 5 六. 主要参考文献 ......................................................... 6 七.附录(所有代码) ...................................................... 7

一.实验目的及实验环境

1.实验目的

《计算机网络》是一门理论性、应用性、实践性比较强的课程。学生只有通过实践,才能理解和掌握计算机网络与通信的有关基本概念、基本原理;通过实践,培养学生的实际动手能力,理论联系实际的能力,综合应用能力,从而培养学生的创新能力。 《计算机网络综合实习》是学习完《计算机网络》课程后进行的一次全面的综合实习,是本专业实践性重要环节之一。本次实习从原理和实践的角度,在计算机上编程模拟实现计算机网络的基本协议,或者架设一个小型局域网并对其进行相应配置。通过本次实习,使学生对计算机网络的基本概念和基本原理有更深入的理解与掌握,同时进一步提高学生的动手能力及解决实际问题的能力。

2.实验环境

本软件采用Java语言编写,本程序基于java和MyEclipse Java Enterprise开发环境,可以在一般的装有windows系统的主机上运行。而网络传输方面采用TCP/IP网络传输协议。

二.实验内容

实现一个一对一的聊天程序。其基本过程如下:服务器首先启动,创建套接字后等待客户的连接;客户启动以后,创建套接字,然后和服务器建立连接;连接建立后,客户机和服务器可以通过建立的套接字连接进行通信。服务器和客户端可以是一台电脑上的两个进程,也可以分别部署在两台电脑上。

三.方案设计

1

1.设计概要

(1)本软件客户端与用户共用一段程序。客户端编译运行后,在窗口选择----侦听。用户编译运行后,在窗口选择----连接。 (2)本软件实现的功能有:

1)允许服务器侦听客户端,客户端连接到服务器 2)允许服务区与客户端之间进行聊天; 3)允许服务器与客户端更改背景颜色; 4)允许服务器与客户端更改字体颜色; 5)服务器与客户端时,会显示内容发送时间;

6)允许服务器与客户端用鼠标点击“发送”,按ENTER键均可发送内容 7)允许服务器与客户端用鼠标点击关闭时关闭聊天窗口

2.功能要求

(1)在服务器端和客户端分别创建一个套接字对象,通过输入输出流连接在一起。套接字调用close()方法关闭双方的套接字连接。

(2)使用多线程处理套接字连接,把服务器端或客户端读取的数据放在一个单独的线程中去进行,防止服务器端或客户端读取数据可能引起的堵塞。服务器端收到一个客户的套接字后,应该启动一个专门为该客户服务的线程。

(3)成功连接后,在图形界面中用户可以根据自己的需要进行不同的操作,如:群聊天、和某一个用户单独聊天(可加入生动的表情描述)、发送文件等。 在界面中会显示用户的聊天记录。 (4)登录功能.

(5)客户可以通过服务器转发,实现一对一和多对多聊天. (6)实现呼叫功能.

(7)客户端程序应该可以实时显示目前其它用户的状态.

2

3.功能设计

1)流程图 服务器进程 像操作系统注 册服务 ServreSocket(port) Serverocket.accept() 等待客户连接, 返回 如果收到客户 连接请求, 就返 Socket 交换程序 回 Socket 对象, OutputStream 表示建立了与 IutputStream 客户的链接 Socket.close()

断开连接 客户进程 Socket(host,port) OutputStream IutputStream Socket.close() 请求与服务器连接,Socket对象创建好,表示连接成功。 断开连接 服务器与客户利用ServerSocket和Socket来通信 2)功能实现

(1)Socket socket = new Socket(String host,int port);客户端创建Socket对象,host是服务器端的IP地址,port是一个端口号,该对象用于连接服务器。

(2)BufferedReader br=new BufferedReader

(new InputStreamReader(socket.getInputStream())); 创建一个使用默认大小输入缓冲区的缓冲字符输入流。该输入流的指向是一个Reader流,Reader流将数据读入缓冲区,BufferedReader再从缓冲区中读取数据。InputStreamReader是字节流通向字符流的桥梁:它使用指定的charset读取字节并将其解码为字符。getInputStream()获取字节输入流。

(3)PrintStream ps = new PrintStream(socket.getOutputStream());创建新的打印流,PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream 永远不会抛出 IOException;而是,异常情况仅设置可通过 checkError 方法测试的内部标志。

(4)File file = getFile();调用getFile()函数返回一个file的的路径,提示用户输入一个路径,判断是否存在该文件, 如果输入非法给予提示, 重新输入。

(5)ps.println(file.getName()); ps.println(file.length());将文件名和大小发送到服务端。 (6)String msg = br.readLine();if(\已存在\ 接收服务器发送回来的是否

3

存在的结果. 如果文件已存在, 打印提示, 客户端退出. 如果不存在, 准备开始上传。

(7)long finishLen = Long.parseLong(msg); 服务器端文件的长度。

(8)FileInputStream fis = new FileInputStream(file); 创建FileInputStream从文件中读取数据,OutputStream out = socket.getOutputStream();输出字节流,输出流接收输出字节并将这些字节写出到Socket的输出流。

(9)fis.skip(finishLen); 从输入流中跳过并丢弃finishLen个字节的数据,即跳过服务端已完成的大小。

(10)len = fis.read(byte[] buffer));从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。

` (11)out.write(byte[] b,int off,int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。

四.测试数据及运行结果

1.对话窗口

4

2.实验界面(JAVA)

五.实验总结

本次实习从选题到正式开始实习有些波折,最初因感兴趣选择了本题目,却因为个别原因没有成功选上,一番折腾之后还是拿到了这个题目。拿到题目后便开始查阅各种资料,借鉴前辈的经验之作,程序运行中确是屡屡受挫。五个做相同实验的人没有一个能够成功运行出来,后来多次操作和上网查阅之后发现问题有二,一为端口占用中,解决方法是不断修改端口,其二为运行顺序,应先运行服务端程序后运行客户端程序。对话窗口成功运行之后,觉得聊天窗口太过单调,又通过请教班里“大神”以及上网搜索、查阅书籍资料,终于能将聊天窗口设计的稍微合理和可观。不可否认的是,我们的一对一程序相对微信QQ太过简单,但是当聊天窗口出来的时候,真的是相当激动和自豪。

5

似乎所有的辛苦跟疲惫都烟消云散了。

本次实习,使我了解到理论和实践相结合的重要性,从理论中得出结论,才能真正掌握这门技术,才能提高自己独立思考的能力,在程序设计的过程中,我可以自己解决问题。这让我真正体会到要将一门知识学的更深入,必须加强实践,多练习。

六.主要参考文献

1、《JavaSE程序设计》;青岛东合信息技术有限公司 2、《Visual+C++网络高级编程》;人民邮电出版社

3、《Windows网络与通信程序设计》;人民邮电出版社;王艳平著 4、《UNIX网络编程》;Richard Stevens著 5、《JAVA程序设计基础》

6

七.附录(所有代码)

1.客户端

package src;//声明类所在的包

import java.awt.*;// 引入AWT图形开发包 import java.awt.event.*;//引入图形事件处理包 import java.io.*;//引入输入输出包 import java.net.*;//引入网络相关的包 public class Client extends Frame {

// 声明主类,继承窗体类,也就是客户端的窗体 Socket s = null; // 定义端口类对象 s,因为很多地方要使用到,所以定义为类的属性 DataOutputStream dos = null; // 定义输出流类的对象 DataInputStream dis = null; // 定义输入流类的对象 private boolean bConnected = false; // 客户端是否启动标志 TextField tfTxt = new TextField(); // 定义文本输入行,用来输入聊天内容 TextArea taContent = new TextArea(); // 定义文本域,用来显示聊天记录 Thread tRecv = new Thread(new RecvThread()); // 定义线程对对象,用来接收每个客户端 public static void main(String[] args) { // 主函数,程序入口 new Client().launchFrame(); // 创建客户端实例,并启动 } public void launchFrame() { // 服务端初始化函数 this.setTitle(\巴卫\); // 设置窗口标题 setLocation(400, 300); // 设置窗口位置 this.setSize(300, 300); // 设置窗口大小 add(tfTxt, BorderLayout.SOUTH); // 把文本行加入到窗口 ,并设置它的位置 add(taContent, BorderLayout.NORTH);

7

// 把文本域加入到窗口 pack();

// 把BorderLayout布局的其他模块隐藏

this.addWindowListener(new WindowAdapter() { // 为窗体增加关闭功能,设置窗口事件监听器 public void windowClosing(WindowEvent arg0) { // 覆写窗口关闭事件 disconnect(); // 关闭窗口时调用客户端结束函数 System.exit(0); // 系统退出 } });

tfTxt.addActionListener(new TFListener());

// 为文本行注册事件监听器,就是用户输入消息后,回车把消息发送出去 setVisible(true); // 使窗体可见 connect();

// 窗体初始化后,就立刻和服务器端相连 tRecv.start(); // 启动线程 }

public void connect() { // 服务器端连接函数 try { s = new Socket(\, 8888); // 初始化端口和服务器IP地址 dos = new DataOutputStream(s.getOutputStream()); // 初始化输出流 dis = new DataInputStream(s.getInputStream()); // 初始化输入流 System.out.println(\服务器连接成功\); // 调试语句 bConnected = true; // 客户端启动标志值为真

} catch (UnknownHostException e) { // 捕获未知服务器异常 e.printStackTrace(); // 输出异常信息 } catch (IOException e) { // 捕获输入输出异常 e.printStackTrace(); } }

8

public void disconnect() { // 断开连接函数 try { dos.close(); // 关闭输出流 dis.close(); // 关闭输入流 s.close(); // 关闭断口

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

private class TFListener implements ActionListener { // 声明文本行的事件监听器类

public void actionPerformed(ActionEvent e) { // 覆写文本域的事件响应方法

Date d = new Date();

String str = d.toLocaleString() +\:巴卫 说: \ +tfTxt.getText().trim(); // 获取文本行的内容 tfTxt.setText(\); // 把文本行的内容显示到文本域 try { dos.writeUTF(str); // 向输出流缓冲写数据 dos.flush(); // 数据发送 } catch (IOException e1) { e1.printStackTrace(); } } }

private class RecvThread implements Runnable {

// 声明线程类,用来接收服务器对应线程发来的消息 public void run() { // 线程启动函数 try { while (bConnected) {

}

String str = dis.readUTF(); // 读取缓冲区数据

taContent.setText(taContent.getText() + str + '\\n'); // 把缓冲区内容显示在文本域上

9

}

}

}

} catch (SocketException e) { System.out.println(\退出了,bye!\); // 对方退出提示,非正常退出,像断电之类的 } catch (EOFException e) { System.out.println(\退出了,bye - bye!\); // 正常退出提示 } catch (IOException e) { // 捕获其他异常 e.printStackTrace(); }

2.服务器端

package src; import java.io.*; import java.net.*; import java.util.*; //引入线程相关包 public class Server { // 定义服务器端类 boolean started = false; // 服务器启动标志 ServerSocket ss = null; List clients = new ArrayList(); // 因为要使用多个客户端相连,所以声明客户端数组 public static void main(String[] args) { new Server().start(); } public void start() { try { ss = new ServerSocket(8888); // 设置服务器端口,TCP端口为8888 started = true; } catch (BindException e) { // 捕获打开多个服务器端的异常 System.out.println(\端口使用中....\); System.out.println(\请关掉相关程序并重新运行服务器!\); System.exit(0); } catch (IOException e) { e.printStackTrace(); } try {

10

while (started) { Socket s = ss.accept(); // 服务器启动后,接收自客户端的消息 Client c = new Client(s); // 创建客户端进程 new Thread(c).start(); // 启动客户端进程 clients.add(c); // 加入到客户端列表 }

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

class Client implements Runnable { // 声明客户端线程类 private Socket s;

private DataInputStream dis = null; private DataOutputStream dos = null; private boolean bConnected = false; public Client(Socket s) { // 客户端线程构造函数 this.s = s; try { dis = new DataInputStream(s.getInputStream()); dos = new DataOutputStream(s.getOutputStream()); bConnected = true; } catch (IOException e) { e.printStackTrace(); } }

public void send(String str) { // 发送消息函数 try { dos.writeUTF(str); } catch (IOException e) { clients.remove(this); System.out.println(\对方退出了!\);

11

} }

public void run() { }

}

}

try { while (bConnected) { // 向每个客户端发消息 String str = dis.readUTF(); for (int i = 0; i < clients.size(); i++) { Client c = clients.get(i); c.send(str); } } } catch (EOFException e) { System.out.println(\客户端退出!\); } catch (IOException e) { e.printStackTrace(); } finally { try { if (dis != null) dis.close(); if (dos != null) dos.close(); if (s != null) { s.close(); } } catch (IOException e1) { e1.printStackTrace(); } }

12

课程设计成绩评定表

学生姓名 专业班级 设计题目 实现一个一对一的聊天程序 指导教师评语及意见: 指导教师评阅成绩: 指导教师签字: 年 月 日

本文来源:https://www.bwwdw.com/article/hmao.html

Top