20202324 實驗四 《資料結構與面向物件程式設計》實驗報告
# 20202324 2021-2022-1 《資料結構與面向物件程式設計》實驗報告
課程:《程式設計與資料結構》
班級: 2023
姓名:肖郅宇
學號:202023124
實驗教師:王志強
實驗日期:2021年10月12日
必修/選修: 必修
## 1.實驗內容
(一)Java Socket程式設計
1.學習藍墨雲上教材《Java和Android程式設計》“第16章 輸入/輸出 ”和“第22章 網路”,學習JavaSocket程式設計
2.結對程式設計。結對夥伴A編寫客戶端SocketClient.java,結對夥伴B編寫伺服器端。
3.截圖加學號水印上傳藍墨雲,程式碼push到碼雲,並撰寫實驗報告。
(二)Java和密碼學
參考 http://www.cnblogs.com/rocedu/p/6683948.html
以結對的方式完成Java密碼學相關內容的學習(帖子中所有程式碼和相關知識點需要學習)。提交學習成果碼雲連結和代表性成果截圖,要有學號水印。
(三)編寫有理數/複數計算器
結對程式設計,結對夥伴A編寫有理數計算器。結對夥伴B編寫複數計算器。截圖加水印上傳藍墨雲,程式碼push碼雲。
(四)遠端有理數計算器
結對程式設計,結對夥伴A程式設計實現客戶端,結果夥伴B實現伺服器端。
客戶端通過鍵盤輸入一個有理數計算的公式(例如:1/4 + 1/6 = ),並把該公式以字串的形式傳送給夥伴B(伺服器端),伺服器端根據字串計算出結果為5/12,並把結果返回給客戶端A,A收到結果後輸出結果。截圖加水印上傳藍墨雲,程式碼push碼雲。
(五)遠端複數計算器
結對程式設計,結對夥伴B程式設計實現客戶端,結果夥伴A實現伺服器端。
客戶端通過鍵盤輸入一個有理數計算的公式(例如:1/4 + 1/6 = ),並把該公式以字串的形式傳送給夥伴A(伺服器端),伺服器端根據字串計算出結果為5/12,並把結果返回給客戶端B,B收到結果後輸出結果。截圖加水印上傳藍墨雲,程式碼push碼雲。
## 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(2324);
//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("The Server has been established!");
while(!((info = bufferedReader.readLine()) ==null)){
System.out.println("你猜猜我想說什麼:" + info);
}
//給客戶一個響應
String reply="WUHUFLY!!!";
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 {
//1.建立客戶端Socket連線,指定伺服器位置和埠
Socket socket = new Socket("172.16.43.44",2324);
//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 = " 使用者名稱:Dogxzy,密碼:iamdog";
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();
}
}
實驗成果截圖
(三)編寫有理數/複數計算器
實驗程式碼
複數類
import java.util.Scanner;
public class Plural extends Calculate{
public static void main(String[] args) {
String next = "y";
String s;
do{
Scanner scan = new Scanner(System.in);
System.out.println("請輸入複數運算式,各符號數字間用空格隔開,負數除外(如:( 1 + 2 i ) + ( 2 + -3 i ) ):");
Calculate ff;
ff = new Plural();
s = scan.nextLine();
ff.Faction(s);
Calculate count;
count = new Plural();
switch (ch){
case '+':
{
count.Add();
break;
}
case '-':
{
count.Sub();
break;
}
case '*':
{
count.Mul();
break;
}
case '/':
{
count.Div();
break;
}
default:
System.out.println("Illegal input!");
break;
}
System.out.println(count.toString(s));
System.out.print("如果您想要繼續計算,請輸入y,否則輸入其他: ");
choose = scan.nextLine();
}while(choose.equals(next));
}
}
分數類
import java.util.StringTokenizer;
public class fenshu {
int fenzi,fenmu;
char ch;
public fenshu(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 fenshu 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;
}
}
fenshu result=new fenshu(fz+"/"+fm);
return result;
}
public fenshu getJia(fenshu x){
int newFenmu=this.fenmu*x.fenmu;
int newFenzi=fenzi*x.fenmu+x.fenzi*fenmu;
return yuefen(newFenzi,newFenmu);
}
public fenshu getJian(fenshu x){
int newFenmu=fenmu*x.fenmu;
int newFenzi=fenzi*x.fenmu-x.fenzi*fenmu;
return yuefen(newFenzi,newFenmu);
}
public fenshu getCheng(fenshu x){
int newFenmu=fenmu*x.fenmu;
int newFenzi=fenzi*x.fenzi;
return yuefen(newFenzi,newFenmu);
}
public fenshu getChu(fenshu x){
int newFenmu=fenmu*x.fenzi;
int newFenzi=fenzi*x.fenmu;
return yuefen(newFenzi,newFenmu);
}
@Override
public String toString() {
return fenzi + "/" + fenmu;
}
}
有理數計算器
public class RationalNumberCalculator {
public static void main(String[] args) {
fenshu result;
fenshu fenshu1;
if(args[0].contains("/")){
fenshu1=new fenshu(args[0]);
}
else{
fenshu1=new fenshu(args[0]+"/"+1);
}
fenshu fenshu2;
if(args[2].contains("/")){
fenshu2=new fenshu(args[2]);
}
else{
fenshu2=new fenshu(args[2]+"/"+1);
}
char ch=args[1].charAt(0);
switch (ch)
{
case '+':
result=fenshu1.getJia(fenshu2);
System.out.println(fenshu1+String.valueOf(ch)+fenshu2+"="+result);
break;
case '-':
result=fenshu1.getJian(fenshu2);
System.out.println(fenshu1+String.valueOf(ch)+fenshu2+"="+result);
break;
case '*':
result=fenshu1.getCheng(fenshu2);
System.out.println(fenshu1+String.valueOf(ch)+fenshu2+"="+result);
break;
case '/':
result=fenshu1.getChu(fenshu2);
System.out.println(fenshu1+String.valueOf(ch)+fenshu2+"="+result);
break;
default:
System.out.println("Illegal input!");
break;
}
}
}
複數計算器
import java.util.StringTokenizer;
public abstract class Calculate {
static double a,b,c,d;
double RealPart;
double ImagePart;
static String choose;
public static char ch;
public void Add() {
RealPart = a + c;
ImagePart = b + d;
}
public void Sub() {
RealPart = a - c;
ImagePart = b - d;
}
public void Mul() {
RealPart = a*c - b*d;
ImagePart = b*c + a*d;
}
public void Div() {
RealPart = (a*c + b*d)/(c*c + d*d);
ImagePart = (b*c + a*d)/(c*c + d*d);
}
public String toString(String s) {
if(ImagePart >= 0){
return s + "=" + RealPart + "+" + ImagePart + "i";
}else {
return s + "=" + RealPart +""+ ImagePart + "i";
}
}
public void Faction(String f){
char z; //取出不用於計算的符號
StringTokenizer st = new StringTokenizer(f, " ", false);
z = st.nextToken().charAt(0);
a = Double.parseDouble(st.nextToken());
z = st.nextToken().charAt(0);
b = Double.parseDouble(st.nextToken());
z = st.nextToken().charAt(0);
z = st.nextToken().charAt(0);
ch = st.nextToken().charAt(0);
z = st.nextToken().charAt(0);
c = Double.parseDouble(st.nextToken());
z = st.nextToken().charAt(0);
d = Double.parseDouble(st.nextToken());
}
}
(四)遠端有理數計算器
實驗程式碼
①伺服器端
import java.io.*;
import java.net.ServerSocket;
import java.net.*;
import java.util.StringTokenizer;
public class server2 {
private static fenshu frac2;
private static fenshu frac1;
private static String a,b;
private static char ch;
private static fenshu result = null;
public static void main(String[] args) throws IOException {
//1.建立一個伺服器Socket(ServerSocket)繫結指定埠
ServerSocket serverSocket=new ServerSocket(2324);
//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("The server has been Established by xzy or wxy");
while(!((info = bufferedReader.readLine()) ==null)){
System.out.println("猜猜我要說什麼,使用者的加密資訊為:"+ info);
String s= info;
String es="";
int key = -4;
for(int i=0;i<s.length( );i++)
{ char c=s.charAt(i);
if(c>=0 && c<=127) // 是小寫字母
{ c+=key%26; //移動key%26位
if(c<0) c+=127; //向左超界
if(c>127) c-=127; //向右超界
}
es+=c;
}
System.out.println("沒想到吧,使用者的解密後的資訊竟然是:" + es);
StringTokenizer st = new StringTokenizer(es, " ", false);
a=st.nextToken();
ch=st.nextToken().charAt(0);
b=st.nextToken();
frac1=new fenshu(a);
frac2=new fenshu(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;