合工大Java实验报告

更新时间:2024-01-28 07:59:01 阅读量: 教育文库 文档下载

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

实 验 报 告

课程名称: Java技术 学生姓名: 学号: 专业班级:

指导教师:

年 月 日

实验一

学院 课程 名称 教信息工程系 Java技术 Java开发环境的安装与配置

姓名 学号 指导教师 成绩 专业 班级 实验项目 名 称 实验一 Java开发环境的安装与配置 师 评 教师签名: 语 年 月 日 一、实验目的 1. 掌握JDK的安装步骤。 2. 理解环境变量PATH, CLASSPATH的作用,以及它们的设置方法(Win XP、WIN7、WIN8、WIN10、Linux下的不同设置方法)。 3. 熟悉TextPad(JCreator或Eclipse)编辑环境,编写简单的Application程序,并编译和解释执行。 4. 记录编译和执行Java程序当中的系统错误信息提示,并给出解决办法。 二、实验原理 1.源程序编译:使用Eclipse或者Notepad++ 2.程序编译:使用JDK中的javac工具 3.程序运行:使用java工具或者使用Eclipse直接运行 4.掌握安装JDK以及环境变量的设置 5. 在Notepad++环境下编写一个HelloWorld.java程序,在DOS提示符下编译并执行这个程序 6. 编写一个类A,它位于包a中,保存到A.java中,再编写一个类B,它位于包b中,保存到B.java中。在类B中实例化类A的一个对象。分别编译类A和类B。 三、使用硬件、软件环境 硬件环境:i5-7200U+8G内存+256G硬盘 软件环境:Windows 10操作系统 开发工具:Eclipse

四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等) 1.从http://www.oracle.com/technetwork/java 下载最新版本的JDK,并安装。(或者用已有文件安装) 安装过程: 安装Jdk集成环境,安装成功后,配置path,classpath路径,让用户在任何目录下均可用到Java的系统资源 ① 先配置%JAVA_HOME%环境变量,路径为jdk的目录; ② 配置path环境变量,路径为%JAVA_HOME%\\bin; ③ 再配置classpath环境变量路径为;%JAVA_HOME%\\lib;%JAVA_HOME%\\lib\\tools.jar 2.设置环境变量PATH, CLASSPATH, 使得Java程序能正确编译和执行。 3.在 Textpad(JCreator或Eclipse)环境下编写一个HelloWorld.java程序,在DOS提示符下编译并执行这个程序。 实验过程: 在Notepad++中写出如下代码,并保存为HelloWorld.java: 源代码: public class HelloWorld { } 在命令行中进入到该文件路径,并输入javac HelloWorld.java完成编译,再public static void main(String[] args) { } System.out.println(\

输 入java HelloWorld完成运行 运行结果: 4.编写一个类A,它位于包a中,保存到A.java中,再编写一个类B,它位于包b中,保存到B.java中。在类B中实例化类A的一个对象。分别编译类A和类B。 实验过程: 用Eclipse编写包 a 包 b 的程序,并用 DOS 命令行运行。 源代码: A: package a; public class A { } B: package b; import a.*; public class B { public static void main(String[] args) { A a = new A(); public void OUT() { } System.out.println(\

} } a.OUT(); 运行结果: 五、实验结论、分析、思考题与心得体会 心得体会 通过本次实验,我对于Java的一些基本知识有所了解,下面我将进行总结: 1.我学习了如何安装JDK,以及配置JAVA环境 2.我学习了使用Notepad++记事本环境下编写Java程序,并使用命令行来编译执行程序 3.我学会了在Eclipse环境下编写与运行Java程序。 4.我对于Java的一些基本语法与使用有所了解,包括: ①文件名必须与public类的类名相同,一个Java应用程序最多只允许有一个public类,并且有且只允许有一个主类, ②Java对于大小写敏感,同时支持中文标识符 ③开发一个Java程序需要经过三个步骤:编写源程序、编译源文件生成字节码、加载运行字节码 ④ 在用DOS命令运行包中的Java文件时,要先编译A.Java,再编译B.Java,同时注意运行有包名的主类时,要使用包名.主类名,即java b.B 思考题 1. 什么是JVM,它的作用是什么? JVM是Java虚拟机。它是一个虚构出来的计算机。可在实际的计算机上模

拟各种计算机功能。 作用:将.class字节码文件编译成机器语言,以便机器识别。 2. 如何理解PATH和CLASSPATH,如何设置它们。 path是系统用来指定可执行文件的完整路径 java的各种操作命令是在其安装路径中的bin目录下,所以在path中设置了JDK的安装目录后就不用再把java文件的完整路径写出来了,它会自动去path中设置的路径中去找; classpath是指定你在程序中所使用的类(.class)文件所在的位置 在引入一个类时:import javax.swing.JTable这句话是告诉编译器要引入javax.swing这个包下的JTable类,而classpath就是告诉编译器该到哪里去找到这个类 假设JDK安装路径: E:\\Program Files\\Java\\jdk 变量名:PATH 变量值:E:\\Program Files\\Java\\jdk\\bin 变量名:CLASSPATH 变量值:E:\\Program Files\\Java\\jdk1\\lib\\tools.jar; E:\\Program Files\\Java\\jdk1\\jre\\lib\\dt.jar

实验二 类的封装、继承、多态

学院 课程 名称 教信息工程系 Java技术 专业 班级 实验项目 名 称 姓名 学号 指导教师 成绩 实验二 类的封装、继承、多态 师 评 教师签名: 语 年 月 日 一、实验目的 1. 复习、理解OOP的三大特征——封装、继承和多态。 2. 学会使用Java编写简单的类。理解类的属性和方法。 3. 掌握关键字private, protected, public的作用,掌握静态类,内部类的概念。 4. 掌握多态的概念。 二、实验原理 1.分别编写两个类Point2D,Point3D来表示二维空间和三维空间的点,使之满足下列要求: (1) Point2D有两个整型成员变量x, y (分别为二维空间的X,Y方向坐标),Point2D的构造方法要实现对其成员变量x, y的初始化。 (2) Point2D有一个void型成员方法offset(int a, int b),它可以实现Point2D的平移。 (3) Point3D是Point2D的直接子类,它有有三个整型成员变量x,y,z (分别为三维空间的X,Y,Z方向坐标),Point3D有两个构造方法:Point3D(int x,int y,int z)和Point3D(Point2D p,int z),两者均可实现对Point3D的成员变量x, y,z的初始化。 (4) Point3D有一个void型成员方法offset(int a, int b,int c),该方法可以实现Point3D的平移。 (5) 在Point3D中的主函数main()中实例化两个Point2D的对象p2d1,p2d2,打印出它们之间的距离,再实例化两个Point3D的对象p3d1,p3d2,打印出他

们之间的距离。 2.创建一个数组,随机生成Point2D或者Point3D的对象放于其中。最后依次调用数组中每个对象的“打印方法” ,显示数组中存储的对象是什么。 提示:java.lang.Math.random()方法 或者 java.util.Random类 三、使用硬件、软件环境 硬件环境:i5-7200U+8G内存+256G硬盘 软件环境:Windows 10操作系统 开发工具:Eclipse 四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等) 1.分别编写两个类Point2D,Point3D来表示二维空间和三维空间的点: (1) Point2D有两个整型成员变量x, y (分别为二维空间的X,Y方向坐标),Point2D的构造方法要实现对其成员变量x, y的初始化。 (2) Point2D有一个void型成员方法offset(int a, int b),它可以实现Point2D的平移。 (3) Point3D是Point2D的直接子类,它有有三个整型成员变量x,y,z (分别为三维空间的X,Y,Z方向坐标),Point3D有两个构造方法:Point3D(int x,int y,int z)和Point3D(Point2D p,int z),两者均可实现对Point3D的成员变量x, y,z的初始化。 (4) Point3D有一个void型成员方法offset(int a, int b,int c),该方法可以实现Point3D的平移。 (5) 在Point3D中的主函数main()中实例化两个Point2D的对象p2d1,p2d2,打印出它们之间的距离,再实例化两个Point3D的对象p3d1,p3d2,打印出他们之间的距离。 利用类的继承写一个 point2D 类,其子类是 point3D 。子类 Point3D 的构造函数调用了父类的构造函数; 计算平面两点的距离函数和计算空间两点的距离函数写在父类 Point2D 中,并且他们是静态方法, 在子类继承

后, 在其主方法 (主方法是静态的) 中可以直接调用 (或者通过类名调用) ;另外平移函数可以对点进行平移 源代码: import java.util.*; import java.lang.Math; class Point2D { int X, Y; public Point2D() { //无形参的构造方法,一定要有 } public Point2D(int x,int y) { this.X=x; this.Y=y; } public void offset(int a, int b)//2D平移方法 { this.X+=a; this.Y+=b; } public void printInfo() { System.out.println(\+this.X+\+this.Y); } public void distance(Point2D p) { double DT=1; DT*=(this.X-p.X)*(this.X-p.X)+(this.Y-p.Y)*(this.Y-p.Y); System.out.println(\距离:\+Math.sqrt(DT)); } } class Point3D extends Point2D { int Z; public Point3D() { //无形参的构造方法,一定要有 } public Point3D(int x,int y,int z) {

this.X=x; this.Y=y; this.Z=z; } Point3D(Point2D p,int z) { this.X=p.X; this.Y=p.Y; this.Z=z; } public void offset(int a, int b,int c)//3D平移方法 { this.X+=a; this.Y+=b; this.Z+=c; } public void printInfo() { System.out.println(\+this.X+\+this.Y+\\+this.Z); } public void distance(Point3D p) { double DT=1; DT*=(this.X-p.X)*(this.X-p.X)+(this.Y-p.Y)*(this.Y-p.Y)+(this.Z-p.Z)*(this.Z-p.Z); System.out.println(\距离:\+Math.sqrt(DT)); } } public class Alex { public static void main(String args[]) { System.out.print(\录入信息*****\\n\); Scanner cin = new Scanner(System.in); int x[]=new int[2]; int y[]=new int[2]; int z[]=new int[2]; for(int i=1;i<3;i++) { System.out.print(\录入第 \+ i +\个 2D 平面坐标\\n 输入横坐标X:\); x[i-1]=cin.nextInt();

System.out.print(\输入纵坐标Y:\); y[i-1]=cin.nextInt(); } Point2D _2Dp1=new Point2D(x[0],y[0]); Point2D _2Dp2=new Point2D(x[1],y[1]); _2Dp1.printInfo(); _2Dp2.printInfo(); System.out.println(\现在将 2D 平面图,3D 化,请给出 竖坐标Z的值\); for(int i=1;i<3;i++) { System.out.print(\录入第 \+ i +\个 3D 平面坐标\\n 输入竖坐标Z:\); z[i-1]=cin.nextInt(); } Point3D _3Dp1=new Point3D(_2Dp1,z[0]); Point3D _3Dp2=new Point3D(_2Dp2,z[1]); _3Dp1.printInfo(); _3Dp2.printInfo(); System.out.println(\平移 2D 图形:\); for(int i=1;i<3;i++) { System.out.print(\录入第 \+ i +\个 2D 图形的平移量\\n 输入横坐标X的平移量:\); x[i-1]=cin.nextInt(); System.out.print(\输入纵坐标Y的平移量:\); y[i-1]=cin.nextInt(); } _2Dp1.offset(x[0], y[0]); _2Dp2.offset(x[1], y[1]); _2Dp1.printInfo(); _2Dp2.printInfo(); for(int i=1;i<3;i++) { System.out.print(\录入第 \+ i +\个 3D 图形的平移量\\n 输入竖坐标Z的平移量:\); z[i-1]=cin.nextInt(); } _3Dp1.offset(x[0],y[0],z[0]); _3Dp2.offset(x[1],y[1],z[1]); _3Dp1.printInfo(); _3Dp2.printInfo(); _2Dp1.distance(_2Dp2); _3Dp1.distance(_3Dp2);

} } 运行结果:

2.创建一个数组,随机生成Point2D或者Point3D的对象放于其中。最后依次调用数组中每个对象的“打印方法” ,显示数组中存储的对象是什么。 思想:使用Math.random()生成数组个数,点的个数1-5个,接着依次给Point2D数组P随机输入一个1-50的整数,接着每次调用,调用Point2D中方法printInfo(),输出点,除了第一次每次调用P[i].distance(P[i - 1]),输出当前点与上一个点的距离。 Point3D数组同上操作 源代码:除了主类外,其它同1中的代码,下面给出主类 public class Point { public static void main(String[] args) { Point2D []P=new Point2D[(int)(Math.random()*5) + 1];//随机生成数组个数 System.out.println(\输出2D数组,并输出与上一点的距离:\); for(int i=0;i

System.out.println(); System.out.println(\输出3D数组,并输出与上一点的距离:\); Point3D []P1=new Point3D[(int)(Math.random()*5) + 1];//随机生成数组个数 for(int i=0;i

五、实验结论、分析、思考题与心得体会 心得体会 通过本次实验,我对于Java如何实现类的继承、封装、多态有了初步的了解,并且学会了如何使用Java语言编写简单的类,理解了类的属性和方法,同时掌握关键字private, protected, public的作用,以及静态类,内部类、多态的概念 在实验过程中,也有了一些心得体会:

①子类继承父类的非私有成员,但不能继承构造方法,必须用super()来调用父类的构造方法。 ②构造方法可以通过形参的个数、类型、排列不同来重载,同时也学会了如何实现类方法的多态。 ③Static静态方法只能直接调用静态成员,不能直接调用非静态成员, ④基本掌握了Math 类中静态方法,Math.pow() 和 Math.sqrt()的使用,同时学会了如何使用Math. random()生成随机数,和如何建立对象的数组。 思考题 什么是类的多态性。 一是操作名称的多态,即多个操作具有相同的名字,但这些操作所接收的信息类型必须不同。所谓操作名称的多态,是指可以向操作传递不同的信息,以便让对象根据相应的信息来产生一定的行为。 另一种多态是和继承有关的多态,是指同一个操作数被不同类型对象调用时可能产生不同的行为。

实验三 输入输出流

学院 课程 名称 教信息工程系 Java技术 专业 班级 实验项目 名 称 姓名 学号 指导教师 成绩 实验三 输入输出流 师 评 教师签名: 语 年 月 日 一、实验目的 1. 掌握Java I/O基本原理。 2. 学会使用Java提供的实用类来完成特定的功能。 3. 掌握FileInputStream、FileOutputStream抽象类的基本使用方法。 4. 掌握FileReader、FileWriter、BufferedReader、BufferedWriter抽象类的基本使用方法。 二、实验原理 1. 使用FileInputStream、FileOutputStream、FileReader、FileWriter、BufferedReader、BufferedWriter抽象类实现从文件中读取内容,并添加所想要输入的内容,接着一行一行输入到另一个文件中。 2. 实现给出的Java Application程序,并分析其功能。 3. 现有如下格式的成绩单(文本格式)score.txt: 姓名:张三,数学72分,物理67分,英语70分. 姓名:李四,数学92分,物理98分,英语88分. 姓名:周五,数学68分,物理80分,英语77分. 要求按给定的程序模板编写一个Java程序,能按行读入上述格式的成绩单,并在该行的后面尾加上该同学的总成绩,然后再将该行写入到一个名字为socreAnalysis.txt的文件中。 三、使用硬件、软件环境 硬件环境:i5-7200U+8G内存+256G硬盘 软件环境:Windows 10操作系统

开发工具:Eclipse 四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等) 1.该程序的功能是通过处理字节流的抽象类:InputStream和OutputStream 完成文件的复制:先使用字节流从“copyFile.java”文件中读取数据,接着将读取到的数据写入到“temp.txt”文件中去,实现copy功能。 源代码: import java.io.*; public class CopyFile { public static void main(String[] args) { try { FileInputStream fis = new FileInputStream(\); FileOutputStream fos = new FileOutputStream(\); int read = fis.read(); while ( read != -1 ) { fos.write(read); read = fis.read(); } fis.close(); fos.close(); } catch (IOException e) { System.out.println(e); } } } 运行结果:

2. AnalysisResult.java源代码: import java.io.*; import java.util.*; public class AnalysisResult{ public static void main(String args[]){ File fRead=new File(\); File fWrite=new File(\); try{ Writer out= new FileWriter(fWrite,true);//以尾加方式创建指向文件fWrite的out流 BufferedWriter bufferWrite=new BufferedWriter(out); //创建指向out的bufferWrite流 Reader in=new FileReader(fRead); //创建指向文件fRead的in流 BufferedReader bufferRead=new BufferedReader(in); //创建指向in的bufferRead流 String str=null; while ((str=bufferRead.readLine())!=null){ double totalScore =Fenxi.getTotalScore(str); str=str+\总分:\+totalScore; System.out.println(str); bufferWrite.write(str); bufferWrite.newLine(); } bufferRead.close(); bufferWrite.close(); }

catch(IOException e){ System.out.println(e.toString()); } } } Fenxi.java源代码: import java.util.*; public class Fenxi{ public static double getTotalScore(String s){ Scanner scanner=new Scanner(s); scanner.useDelimiter(\); double totalScore=0; while(scanner.hasNext()){ try{ double score=scanner.nextDouble(); totalScore=totalScore+score; } catch(InputMismatchException exp){ String t=scanner.next(); } } return totalScore; } } 运行结果: 记事本信息:

五、实验结论、分析、思考题与心得体会 通过本次实验,我对于Java语言关于输入输出流的部分有了一定的了解,下面是我的一些收获: 1. 掌握Java I/O基本原理:Java中的IO包中的类可以处理不同类型的流,例如:字节流(byte[])、字符流(character)、文件流、对象流等。 java.io中的抽象类包括:处理字节流的抽象类:InputStream和OutputStream,处理过滤流的抽象类:FilterOutputStream和FilterInputStream,处理字符流的抽象类:Reader和Writer,处理压缩流的抽象类:InflaterInputStream和DeflaterOutputStream 2.学会如何使用Java给出的各种输入输出流来实现一系列的问题,包括:从文件的读取数据、使用输出流对数据进行加工存储到文件中等。 3.掌握了FileInputStream、FileOutputStream抽象类的基本使用方法,并实际操作实现了读取与存储拷贝。 4.掌握了FileReader、FileWriter、BufferedReader、BufferedWriter抽象类的基本使用方法,实现修改读取的内容,添加内容存储进入文件中。

实验四 基于GUI的网络通信程序设计

学院 课程 名称 教信息工程系 Java技术 专业 班级 实验项目 名 称 姓名 学号 指导教师 成绩 实验四 基于GUI的网络通信程序设计 师 评 教师签名: 语 年 月 日 一、实验目的 1. 掌握Java中GUI程序的编写,包括事件监听机制。 2. 掌握Java的网络通信编程,ServerSocket,Socket类的使用。 3. 掌握Java中多线程的编程,Thread类,Runnable接口的使用。 4. 掌握用面向对象的方法分析和解决复杂问题。 二、实验原理 使用Java Swing中的组件实现GUI程序的编写,包括使用监听器、ServerSocket,Socket类实现输入输出数据。 同时使用Thread类,Runnable接口,实现多线程执行程序。 (1)设计一个基于GUI的客户-服务器的通信应用程序,如图1,图2所示。 图1 Socket通信服务器端界面 图2 Socket通信客户端界面 (2)图1为Socket通信服务器端界面,点击该界面中的【Start】按钮,启动服务器监听服务(在图1界面中间的多行文本区域显示“Server starting?”字样)。图2为Socket通信客户端界面,点击该界面中的【Connect】按钮与服务器建立链接,并在图2所示界面中间的多行文本区域显示“Connect to server?”字样,当服务器端监听到客户端的连接后,在图1界面中间的多行文

本区域追加一行“Client connected?”字样,并与客户端建立Socket连接。 (3)当图1所示的服务器端和图2所示的客户机端建立Socket连接后,编程实现这两端的数据通信,每次将接收到对方的数据追加显示在多行文本框中。 三、使用硬件、软件环境 硬件环境:i5-7200U+8G内存+256G硬盘 软件环境:Windows 10操作系统 开发工具:Eclipse 四、实验过程、步骤及原始记录(算法、原程序、测试结果,分析等) 1、编写两个文件Client.java 与Server.java,两个Java文件的内容相似,首先在构造方法中写了调用了实现GUI的函数,即使用 JFrame类建立窗口,以及加入相应的组件,使用FlowLayout布局,,也为按钮注册了监听器。在不同的内部类中写了不同监听器所调用的actioPerformed()方法。 通过写一个主类,与一个实现类,主类通过创建实现类的对象来调用其构造方法来实现功能。实现类中包括各种方法与内部类通过方法的层层调用,来实现所需要的结果。 2、在服务器中创建ServerSocked对象来接受客户端的连接请求,并指定端口号,客户端通过Socket对象与客户端的Socket对象连接。连接成功后通过IO流来通信,服务器的输入流是客户端的输出流,服务器的输出流是客户端的输入流,通过BufferedReader读取相应套接字 socket 中获取的输入流的内容,并放入对应的文本框中。 服务器代码: import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; import java.net.*; import javax.swing.*; public class Server{ public static void main(String[] args){ MyFrame serve = new MyFrame(); serve.setTitle(\服务器\); serve.setVisible(true);

serve.setResizable(false); //设置此窗体是否可由用户调整大小 serve.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置默认关闭操作 } } class MyFrame extends JFrame{ JTextField port; JButton start; JTextArea content; JTextField cin; JButton say; Socket socket; MyFrame(){ init(); StartListen sListen = new StartListen(); SayListen stListen = new SayListen(); start.addActionListener(sListen); //为按钮 start 注册一个监听器 say.addActionListener(stListen); //为按钮 say注册一个监听器 } void init(){ setLayout(new FlowLayout()); //设置窗体为流式布局 setSize(400,400); setLocation(400,100); add(new JLabel(\)); port = new JTextField(\,25); add(port); start = new JButton(\); add(start); content = new JTextArea(15,35); JScrollPane scroll = new JScrollPane(content); //设置滚动条 add(scroll); add(new JLabel(\)); cin = new JTextField(\!\,26); add(cin); say = new JButton(\); add(say); } class StartListen implements ActionListener{ public void actionPerformed(ActionEvent e){ start.setEnabled(false);

try { ServerSocket s = new ServerSocket(Integer.parseInt(port.getText())); // 创建一个服务器套接字对象 s,形参为从 port 文本框中读取的整型(端口号) socket = s.accept(); PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);// 创建一个打印输出流对象,其形参为从套接字 socket 对象中获取的输出流 out.println(\); content.append(\+\); //对两个字符串进行拼接 ServerThread st = new ServerThread(); //创建一个 ServerThread 对象st,并调用其构造方法 st.start(); //启动一个线程,并调用 run()方法 } catch (Exception ex) {} } } class SayListen implements ActionListener{ String str; public void actionPerformed(ActionEvent e){ try {PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);// 创建一个打印输出流,形参为从套接字socket 中获取的输出流 str=cin.getText(); if(!str.isEmpty()){ out.println(new Date()+\+str); //打印输出日期和发送的消息( str) content.append(new Date()+\+str+\); out.flush(); //清空缓存区 } cin.setText(\); } catch (Exception ex) {} } } class ServerThread extends Thread{ public void run(){ try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //创建一个缓冲输出流,其形参为从套接字 socket 中获取的输入流 String str; while(true){

} str = in.readLine(); //按行读取 content.append( str+\); } } catch (Exception ex) {} } } 客户端代码: import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; import java.net.*; import javax.swing.*; import java.util.Calendar; public class Client{ public static void main(String[] args) { MyFrame client=new MyFrame(); client.setTitle(\客户端\); client.setVisible(true); client.setResizable(false); //设置此窗体是否可由用户调整大小 client.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭操作 } } class MyFrame extends JFrame { JTextField ip; JTextField port; JTextField cin; JTextArea content; JButton connect; JButton say; Socket socket; MyFrame(){ init(); ConnectListen cListener=new ConnectListen(); SayListen sListener = new SayListen(); connect.addActionListener(cListener); //注册监听器 say.addActionListener(sListener); //注册监听器 } void init(){

setLayout(new FlowLayout()); //设置窗体为流式布局 setSize(440,500); setLocation(800,100); add(new JLabel(\)); ip=new JTextField(\,8); add(ip); add(new JLabel(\)); port=new JTextField(\,8); add(port); connect=new JButton(\); add(connect); content=new JTextArea(16,35); JScrollPane scroll=new JScrollPane(content); //设置滚动条 add(scroll); add(new Label(\)); cin=new JTextField(\你好!\,25); add(cin); say=new JButton(\); add(say); } class ConnectListen implements ActionListener{ int portNum; public void actionPerformed(ActionEvent e){ connect.setEnabled(false); //按下 connect 按钮后, connect 不可再次点击 try { content.setText(\); //在文本区中显示 \ portNum =Integer.parseInt(port.getText()); //读取 port 文本框中的字符串,并将字符串转化为整型赋给 portNum socket = new Socket(ip.getText(),portNum); //定义对象 socket,并指定主机号(host)和端口号 portNum ClientThread ct = new ClientThread(); //定义一个 ClientThread 类的对象 ct ct.start(); //启动一个线程,并调用ClientThread 类中的 run()方法 } catch (Exception ex) {} } } class SayListen implements ActionListener{ String str; public void actionPerformed(ActionEvent e){ try { PrintWriter out = new PrintWriter(new

BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true); //从 socket 获取字节输出流,并将其最终转化为 PrintWriter str=cin.getText(); //从文本框中获取字符串赋给 str if(!str.isEmpty()){ out.println(new Date()+ \+ str); //打印日期和 str content.append(new Date()+\+str+\); out.flush(); //清空缓存区 } cin.setText(\); } catch (Exception ex) {} } } class ClientThread extends Thread{ public void run(){ try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //创建一个缓冲输出流,其形参为从套接字 socket 中获取的输入流 String str; while(true){ str = in.readLine(); //按行读取 content.append( str+\); } } catch (Exception ex) {} } } } 运行结果:

五、实验结论、分析、思考题与心得体会 通过本次实验,我对于GUI程序的便编写,以及网络通信与多线程编程有了一定的了解,并且也亲自实现了一个基于GUI的客户-服务器的通信应用程序,在实验过程中,我也遇到了不少的问题并加以解决: 1.因为服务器的GUI界面有start和say按钮,客户端有connect和say按钮,按钮被点击后会触发动作事件。而不同的按钮要执行不同的操作,也就意味着要写多个actionPerformed()方法,可是一个类里面只能写一个actionPerformed()方法,因此可以写几个实现了ActionPerformed()方法,在内部类中再写一个actionPerformed()方法,这样就写了好几个不同的actionPerformed()方法,在注册监听器的时候,按钮需要实现哪种功能,就用哪个内部类的对象来监听就可以了。 2.在服务器中创建 ServerSocket 对象来接受客户端的连接请求, 并指定端口号, 客户端通过Socket 对象来向服务器的 ip 和端口发送连接请求。服务器在接到连接请求后,服务器会创建一个新的 Socket 对象与客户端的 Socket 对象连接。连接成功后通过 IO 流来通信,服务器的输入流是客户端的输出流,服务器的输出流时客户端的输入流

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

Top