20192318 实验四 《数据结构与面向对象程序设计》实验报告
20192318 2020-2021-1 《数据结构与面向对象程序设计》实验四报告
- 课程:《程序设计与数据结构》
- 班级: 1923
- 姓名: 邢苏
- 学号: 20192318
- 实验教师:王志强
- 实验日期:2020年10月22日
- 必修/选修: 必修
1.实验内容
(一)Java Socket编程
1.学习蓝墨云上教材《Java和Android编程》“第16章 输入/输出 ”和“第22章 网络”,学习JavaSocket编程
2.结对编程。结对伙伴A编写客户端SocketClient.java,结对伙伴B编写服务器端。
(二)Java和密码学
参考 http://www.cnblogs.com/rocedu/p/6683948.html
以结对的方式完成Java密码学相关内容的学习
(三)编写有理数/复数计算器
结对编程,结对伙伴A编写有理数计算器。结对伙伴B编写复数计算器。
(四)远程有理数计算器
结对编程,结对伙伴A编程实现客户端,结果伙伴B实现服务器端。
客户端通过键盘输入一个有理数计算的公式(例如:1/4 + 1/6 = ),并把该公式以字符串的形式发送给伙伴B(服务器端),服务器端根据字符串计算出结果为5/12,并把结果返回给客户端A,A收到结果后输出结果。
(五)远程复数计算器
客户端通过键盘输入一个复数计算的公式,并把该公式以字符串的形式发送给伙伴A(服务器端),服务器端根据字符串计算出结果,并把结果返回给客户端B,B收到结果后输出结果。
2. 实验过程及结果
(一)Java Socket编程
- 编写服务器代码
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Servertest {
public static void main(String[] args) throws IOException {
//1.建立一个服务器Socket(ServerSocket)绑定指定端口
ServerSocket serverSocket=new ServerSocket(4567);
//2.使用accept()方法阻止等待监听,获得新连接
Socket socket=serverSocket.accept();
//3.获得输入流
InputStream inputStream=socket.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
//获得输出流
OutputStream outputStream=socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
//4.读取用户输入信息
String info=null;
System.out.println("服务器已经建立!准备完毕");
while(!((info = bufferedReader.readLine()) ==null)){
System.out.println("实验完成啦:" + info);
}
//给客户一个响应
String reply="Hello!";
printWriter.write(reply);
printWriter.flush();
//5.关闭资源
printWriter.close();
outputStream.close();
bufferedReader.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
- 编写客户端代码
import java.io.*;
import java.net.Socket;
public class SocketClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("192.168.1.241",4567);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
String info1 = " 用户名:SXing,密码:112233445566";
String info = new String(info1.getBytes("GBK"),"GBK");
printWriter.write(info);
printWriter.flush();
outputStreamWriter.write(info1);
outputStreamWriter.flush();
socket.shutdownOutput();
String reply = null;
while (!((reply = bufferedReader.readLine()) ==null)){
System.out.println("接收服务器的信息为:" + reply);
}
bufferedReader.close();
inputStream.close();
outputStreamWriter.close();
printWriter.close();
outputStream.close();
socket.close();
}
}
- 运行结果
(二)Java和密码学
(三)编写有理数/复数计算器
public class Rational
{
public static void main (String[] args)
{
int n,m;
char judge,count;
Scanner scan = new Scanner (System.in);
do
{
System.out.println ("please input +-*/%");
count = scan.next().charAt(0);
System.out.println ("please input n and m");
n = scan.nextInt();
m = scan.nextInt();
switch (count)
{
case '+' :
System.out.println (n + "+" + m + "=" + (n+m));
break;
case '-' :
System.out.println (n + "-" + m + "=" + (n-m));
break;
case '*' :
System.out.println (n + "*" + m + "=" + (n*m));
break;
case '/' :
System.out.println (n + "/" + m + "=" + (n/m));
break;
case '%' :
System.out.println (n + "%" + m + "=" + (n%m));
break;
default :
System.out.println ("error");
}
System.out.println ("do to y or leave to n ");
judge = scan.next().charAt(0);
}while(judge!='n');
}
}
- 运行结果
(四)远程有理数计算器
- 服务器代码
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
public class Server {
private static Fraction frac2;
private static Fraction frac1;
private static String a, b;
private static char ch;
private static Fraction result = null;
public static void main(String[] args) throws IOException {
//1.建立一个服务器Socket(ServerSocket)绑定指定端口
ServerSocket serverSocket = new ServerSocket(8809);
//2.使用accept()方法阻止等待监听,获得新连接
Socket socket = serverSocket.accept();
//3.获得输入流
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//获得输出流
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
//4.读取用户输入信息
String info = null;
System.out.println("服务器已经建立......");
while (!((info = bufferedReader.readLine()) == null)) {
System.out.println("我是服务器,用户信息为:" + info);
StringTokenizer st = new StringTokenizer(info, " ", false);
a = st.nextToken();
ch = st.nextToken().charAt(0);
b = st.nextToken();
frac1 = new Fraction(a);
frac2 = new Fraction(b);
switch (ch) {
case '+':
result = frac1.getJia(frac2);
break;
case '-':
result = frac1.getJian(frac2);
break;
case '*':
result = frac1.getCheng(frac2);
break;
case '/':
result = frac1.getChu(frac2);
break;
default:
break;
}
}
//给客户一个响应
String reply = frac1 + String.valueOf(ch) + frac2 + "=" + result;
printWriter.write(reply);
printWriter.flush();
//5.关闭资源
printWriter.close();
}
}
- 客户端代码
import java.io.*;
import java.net.Socket;
public class Long_Ration_Calculator
{
public static void main(String[] args) throws IOException
{
Socket socket = new Socket("192.168.45.138",8809);
OutputStream outputStream = socket.getOutputStream();
PrintWriter printWriter = new PrintWriter(outputStream);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
String info1 = " 1/4 + 1/6";
String info = new String(info1.getBytes("GBK"),"GBK");
printWriter.write(info);
printWriter.flush();
outputStreamWriter.write(info1);
outputStreamWriter.flush();
socket.shutdownOutput();
String reply = null;
while (!((reply = bufferedReader.readLine()) ==null)){
System.out.println("接收服务器的信息为:" + reply);
}
bufferedReader.close();
inputStream.close();
outputStreamWriter.close();
printWriter.close();
outputStream.close();
socket.close();
}
}
- 建立分数类
import java.util.StringTokenizer;
public class Fraction {
int fenzi,fenmu;
char ch;
public Fraction(String str) {
StringTokenizer st=new StringTokenizer(str,"/",true);
this.fenzi = Integer.parseInt(st.nextToken());
this.ch=st.nextToken().charAt(0);
this.fenmu = Integer.parseInt(st.nextToken());
}
public Fraction yuefen(int fz,int fm){
int i;
for (i=2;i<=fz&&i<=fm;i++){
if(fz%i==0&&fm%i==0){
fz=fz/i;
fm=fm/i;
}
}
Fraction result=new Fraction(fz+"/"+fm);
return result;
}
public Fraction getJia(Fraction x){
int newFenmu=fenmu*x.fenmu;
int newFenzi=fenzi*x.fenmu+x.fenzi*fenmu;
return yuefen(newFenzi,newFenmu);
}
public Fraction getJian(Fraction x){
int newFenmu=fenmu*x.fenmu;
int newFenzi=fenzi*x.fenmu-x.fenzi*fenmu;
return yuefen(newFenzi,newFenmu);
}
public Fraction getCheng(Fraction x){
int newFenmu=fenmu*x.fenmu;
int newFenzi=fenzi*x.fenzi;
return yuefen(newFenzi,newFenmu);
}
public Fraction getChu(Fraction x){
int newFenmu=fenmu*x.fenzi;
int newFenzi=fenzi*x.fenmu;
return yuefen(newFenzi,newFenmu);
}
@Override
public String toString() {
return fenzi + "/" + fenmu;
}
}
- 运行结果
(五)远程复数计算器
- 建立服务器代码
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
public class Server20192318 {
private static Complex11 cplx1;
private static Complex11 cplx2;
private static String a,b;
private static char ch;
private static Complex11 result = null;
public static void main(String[] args) throws IOException {
//1.建立一个服务器Socket(ServerSocket)绑定指定端口
ServerSocket serverSocket=new ServerSocket(8809);
//2.使用accept()方法阻止等待监听,获得新连接
Socket socket=serverSocket.accept();
//3.获得输入流
InputStream inputStream=socket.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
//获得输出流
OutputStream outputStream=socket.getOutputStream();
PrintWriter printWriter=new PrintWriter(outputStream);
//4.读取用户输入信息
String info=null;
System.out.println("服务器已经建立......");
while(!((info = bufferedReader.readLine()) ==null)) {
System.out.println("我是服务器,用户信息为:" + info);
StringTokenizer st = new StringTokenizer(info, " ", false);
a = st.nextToken();
ch = st.nextToken().charAt(0);
b = st.nextToken();
cplx1 = new Complex11(a);
cplx2 = new Complex11(b);
switch (ch) {
case '+':
result = cplx1.ComplexAdd(cplx2);
break;
case '-':
result = cplx1.ComplexSub(cplx2);
break;
case '*':
result = cplx1.ComplexMulti(cplx2);
break;
case '/':
result = cplx1.ComplexDiv(cplx2);
break;
default:
break;
}
}
//给客户一个响应
String reply=cplx1+String.valueOf(ch)+cplx2+"="+result;
printWriter.write(reply);
printWriter.flush();
//5.关闭资源
printWriter.close();
outputStream.close();
bufferedReader.close();
inputStream.close();
socket.close();
serverSocket.close();
}
}
- 建立客户端代码
import java.io.*;
import java.net.Socket;
public class SocketClient1 {
public static void main(String[] args) throws IOException {
//1.建立客户端Socket连接,指定服务器位置和端口
Socket socket = new Socket("192.168.45.138",8809);
// Socket socket = new Socket("192.168.45.138",8800);
//2.得到socket读写流
OutputStream outputStream = socket.getOutputStream();
// PrintWriter printWriter = new PrintWriter(outputStream);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream);
//输入流
InputStream inputStream = socket.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
//3.利用流按照一定的操作,对socket进行读写操作
String info1 = " 4.8 * 5.6";
// String info = new String(info1.getBytes("GBK"),"GBK");
// printWriter.write(info);
// printWriter.flush();
outputStreamWriter.write(info1);
outputStreamWriter.flush();
socket.shutdownOutput();
//接收服务器的响应
String reply = null;
while (!((reply = bufferedReader.readLine()) ==null)){
System.out.println("接收服务器的信息为:" + reply);
}
//4.关闭资源
bufferedReader.close();
inputStream.close();
outputStreamWriter.close();
//printWriter.close();
outputStream.close();
socket.close();
}
}
- 建立Complex11类
import java.util.StringTokenizer;
public class Complex11{
private int RealPart;
private int ImagePart;
private char ch;
//构造函数
public Complex11(){}
public Complex11(String str){
StringTokenizer st=new StringTokenizer(str,".",true);
this.RealPart=Integer.parseInt(st.nextToken());
this.ch=st.nextToken().charAt(0);
this.ImagePart=Integer.parseInt(st.nextToken());
}
//返回
public double getRealPart(){
return RealPart;
}
public double getImagePart(){
return ImagePart;
}
//接收
public void setRealPart(int realPart){
RealPart=realPart;
}
public void setImagePart(int imagePart){
ImagePart=imagePart;
}
//重写函数toString
public String toString(){
return RealPart + "." + ImagePart;
}
public boolean equals(Object a){
if (a==this){
return true;
}
else{
return false;
}
}
// 定义公有方法:加减乘除
public Complex11 ComplexAdd(Complex11 a){
Complex11 b = new Complex11((this.RealPart+a.RealPart)+"."+(this.ImagePart+a.ImagePart));
return b;
}
public Complex11 ComplexSub(Complex11 a){
Complex11 b = new Complex11((this.RealPart-a.RealPart)+"."+(this.ImagePart-a.ImagePart));
return b;
}
public Complex11 ComplexMulti(Complex11 a){
Complex11 b = new Complex11((this.RealPart*a.RealPart-this.ImagePart*a.ImagePart)+"."+(this.ImagePart*a.RealPart+this.RealPart*a.ImagePart));
return b;
}
public Complex11 ComplexDiv(Complex11 a){
double scale = a.getRealPart()*a.getRealPart() + a.getImagePart()*a.getImagePart();
Complex11 b = new Complex11((a.getRealPart() / scale)+"."+
(- a.getImagePart() / scale));
return b;
}
}
- 运行结果
3. 实验过程中遇到的问题和解决过程
- 问题一:在第一个实验中的服务器以客户端的传输信息的时候客户端总是在运行的时候程序运行失败
- 问题一解决方案:将结对双方的网络连接在同一网络状态下,把客户端中的IP地址改变成为同一网络状态下的IP地址即可运行成功
- 问题二:在服务器与客户端传输结果中显示为乱码
- 问题二解决方案:将程序中与下面的UTF-8均改变为GBK,就可以实现程序已中文形式输出
实验心得
- 一个程序编写到实现需要很多很多的步奏,也可能一个程序的实现需要很多行代码,常常会出现一些致命的错误,所以,在编写相应的代码之前,要先想好每一步的具体步奏
- 这次的代码有亿点点多,亿点点难度