生活随笔
收集整理的這篇文章主要介紹了
2018-2019-2 20175224 实验五《网络编程与安全》实验报告
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
實驗內容及步驟
任務一:兩人一組結對編程:
參考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA結對實現中綴表達式轉后綴表達式的功能 MyBC.java結對實現從上面功能中獲取的表達式中實現后綴表達式求值的功能,調用MyDC.java上傳測試代碼運行結果截圖和碼云鏈接實現中綴表達式轉后綴表達式
import java.util.Stack;
import java.util.StringTokenizer;public class MyBC {/** constant for addition symbol */private final char ADD = '+'
;/** constant for subtraction symbol */private final char SUBTRACT = '-'
;/** constant for multiplication symbol */private final char MULTIPLY = '*'
;/** constant for division symbol */private final char DIVIDE = '/'
;/** the stack */Stack<Integer> stack=
new Stack<Integer>
();;String expression;public void setExpression(String str) {expression=
str;}public String changedWay() {String changedExpression = ""
;Stack signStack =
new Stack();
// 操作符棧for (
int i = 0; i < expression.length(); i++
) {char c =
expression.charAt(i);if (c >= '0' && c <= '9'
) {changedExpression=changedExpression+
c;}else if (c == '+' || c == '-' || c == '*' || c == '/'
) {changedExpression=changedExpression+" ";
//分隔數字if (signStack.empty()) {signStack.push(c);}else if (judgeValue(c) >= judgeValue((Character) signStack.peek())) {
//優先級高于或等于,運算符號均進棧
signStack.push(c);}else {changedExpression=changedExpression+(
char)signStack.pop();signStack.push(c);}}else if (c=='('
) {signStack.push(c);}else if (c==')'
) {while((
char)signStack.peek()!='('
) {changedExpression=changedExpression+" "+
signStack.pop();}signStack.pop();}}while(!
signStack.empty()){changedExpression=changedExpression+" "+
String.valueOf(signStack.pop());}return changedExpression;}private static int judgeValue(
char c) {int value = 0
;switch (c) {case '('
:value = 1
;break;case '+'
:case '-'
:value = 2
;break;case '*'
:case '/'
:value = 3
;break;case ')'
:value = 4
;default:value = 0
;}return value;}public int evaluate (String expr){//后綴表達式的運算方法int op1, op2, result = 0
;String token;StringTokenizer tokenizer =
new StringTokenizer (expr);
//使用StringTokenizer類分解String對象的字符序列,默認為空格符...//此時tokenizer為一個分析器while (tokenizer.hasMoreTokens()) {token =
tokenizer.nextToken();if (isOperator(token)){op2 = (stack.pop()).intValue();
//出棧op1 = (stack.pop()).intValue();
//出棧result = evalSingleOp (token.charAt(0), op1, op2);
//String對象第一個字符轉換為char類型的方法為:str.charAt(0)stack.push (
new Integer(result));
//進棧
}else {stack.push(new Integer(Integer.parseInt(token)));
//進棧
}}return result;}private boolean isOperator (String token){return ( token.equals("+") || token.equals("-") ||
token.equals("*") || token.equals("/"
) );}private int evalSingleOp (
char operation,
int op1,
int op2){int result = 0
;switch (operation){case ADD:result = op1 +
op2;break;case SUBTRACT:result = op1 -
op2;break;case MULTIPLY:result = op1 *
op2;break;case DIVIDE:result = op1 /
op2;}return result;}
} 任務二:兩人一組結對編程:
參考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA結對實現中綴表達式轉后綴表達式的功能 MyBC.java結對實現從上面功能中獲取的表達式中實現后綴表達式求值的功能,調用MyDC.java上傳測試代碼運行結果截圖和碼云鏈接- 獲取本機IP地址:DESKTOP-HN1B8O2/172.30.2.248
netAddress address_3=
InetAddress.getLocalHost();
System.out.println(address_3.toString()); - 結對伙伴的IP為:172.30.4.50 所選端口為:1111
- 負責客服端的構建,實現代碼為:
- 選用AES加密算法
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.*
;public class Client_2Socket {public static void main(String[] args) {Socket Client_2Socket;DataInputStream Client_2in=
null;DataOutputStream Client_2out=
null;String expr,str;Scanner scanner=
new Scanner(System.in);System.out.println("請輸入表達式:"
);str=
scanner.nextLine();MyBC mybc=
new MyBC();mybc.setExpression(str);expr=
mybc.changedWay();try {Client_2Socket=
new Socket("172.30.2.248",5353
);Client_2in=
new DataInputStream(Client_2Socket.getInputStream());Client_2out=
new DataOutputStream(Client_2Socket.getOutputStream());Client_2out.writeUTF(expr);String s=
Client_2in.readUTF();System.out.println("服務器回復:\n"+
s);}catch (Exception e) {System.out.println("服務器已斷開"+
e);}}
} import java.io.*
;
import java.net.*
;
import java.util.*
;public class Server_2 {public static void main(String[] args) {ServerSocket Server_2forClient_2=
null;Socket SocketOnServer_2=
null;DataOutputStream Server_2out=
null;DataInputStream Server_2in=
null;try {Server_2forClient_2=
new ServerSocket(5353
);}catch (IOException e1) {System.out.println(e1);//e1.printStackTrace();
}try {System.out.println("等待客戶端呼叫……"
);SocketOnServer_2=
Server_2forClient_2.accept();Server_2out=
new DataOutputStream(SocketOnServer_2.getOutputStream());Server_2in=
new DataInputStream(SocketOnServer_2.getInputStream());String expr=
Server_2in.readUTF();System.out.println("服務器接收到表達式:"+
expr);int result;MyBC mybc=
new MyBC();result=
mybc.evaluate(expr);Server_2out.writeUTF("后綴表達式:"+expr+",運算結果為:"+
result);Thread.sleep(500
);}catch (Exception e2) {System.out.println("客戶端已斷開"+
e2);}}
} 任務三:加密結對編程:1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密后通過網絡把密文發送給服務器服務器接收到后綴表達式表達式后,進行解密(和客戶端協商密鑰,可以用數組保存),然后調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端客戶端顯示服務器發送過來的結果上傳測試結果截圖和碼云鏈接- 思路:密文通過TCP傳輸,而AES密鑰通過機密通道傳輸。
- 負責客服端的構建,代碼為:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.*
;public class Client_3 {public static void main(String[] args) {Socket Client_2Socket;DataInputStream Client_2in=
null;DataOutputStream Client_2out=
null;String expr=
null;String str=
null;String Ciphertext=
null;Scanner scanner=
new Scanner(System.in);System.out.println("請輸入表達式:"
);str=
scanner.nextLine();MyBC mybc=
new MyBC();mybc.setExpression(str);expr=
mybc.changedWay();try {AES.produceAESKey();//生成AES密鑰byte[]cc= AES.EncryptionAES(expr);
//需要傳輸的密文,數組形式傳輸。Ciphertext = Base64.getEncoder().encodeToString(cc);
//將加密后的密文由byte[]轉換為String類型}
catch (Exception e) {e.printStackTrace();}try {Client_2Socket=
new Socket("172.30.2.248",5300
);Client_2in=
new DataInputStream(Client_2Socket.getInputStream());Client_2out=
new DataOutputStream(Client_2Socket.getOutputStream());Client_2out.writeUTF(Ciphertext);String s=
Client_2in.readUTF();System.out.println("服務器回復:\n"+
s);}catch (Exception e) {System.out.println("服務器已斷開"+
e);}}
} import sun.security.krb5.internal.crypto.Aes128;import java.io.*
;
import java.net.*
;
import java.util.*
;public class Server_3 {public static void main(String[] args) {ServerSocket Server_2forClient_2=
null;Socket SocketOnServer_2=
null;DataOutputStream Server_2out=
null;DataInputStream Server_2in=
null;try {Server_2forClient_2=
new ServerSocket(5300
);}catch (IOException e1) {System.out.println(e1);}try {System.out.println("等待客戶端呼叫……"
);SocketOnServer_2=
Server_2forClient_2.accept();Server_2out=
new DataOutputStream(SocketOnServer_2.getOutputStream());Server_2in=
new DataInputStream(SocketOnServer_2.getInputStream());String Ciphertext=Server_2in.readUTF();
//密文byte[] data=
Base64.getDecoder().decode(Ciphertext);String expr=
AES.DecryptionAES(data);System.out.println("服務器接收到表達式:"+
expr);int result;MyBC mybc=
new MyBC();result=
mybc.evaluate(expr);Server_2out.writeUTF("后綴表達式:"+expr+",運算結果為:"+
result);Thread.sleep(500
);}catch (Exception e2) {System.out.println("客戶端已斷開"+
e2);}}
} 任務四:密鑰分發結對編程:1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密通過網絡把密文發送給服務器客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換服務器接收到后綴表達式表達式后,進行解密,然后調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端客戶端顯示服務器發送過來的結果上傳測試結果截圖和碼云鏈接DH算法相關鏈接:
- DH算法原理
-
密鑰交換算法DH(Java實現)
- 密鑰交換實現過程:
- 由消息發送的一方構建密鑰,這里由甲方構建密鑰。
- 由構建密鑰的一方向對方公布其公鑰,這里由甲方向乙方發布公鑰。
- 由消息接收的一方通過對方公鑰構建自身密鑰,這里由乙方使用甲方公鑰構建乙方密鑰。
- 由消息接收的一方向對方公布其公鑰,這里由乙方向甲方公布公鑰。
-
使用密鑰協定創建共享密鑰截圖:
SecretKeySpec k=
new SecretKeySpec(sb,"DESede"
);FileOutputStream f=
new FileOutputStream("A_Key_DESede_DH.dat");
//指定產生密鑰輸出流文件ObjectOutputStream b=
new ObjectOutputStream(f);
//將對象序列化,以流的方式進行處理b.writeObject(k);
//通過以對象序列化方式將密鑰保存在文件中 任務五:完整性校驗結對編程:1人負責客戶端,一人負責服務器
注意責任歸宿,要會通過測試證明自己沒有問題基于Java Socket實現客戶端/服務器功能,傳輸方式用TCP客戶端讓用戶輸入中綴表達式,然后把中綴表達式調用MyBC.java的功能轉化為后綴表達式,把后綴表達式用3DES或AES算法加密通過網絡把密文和明文的MD5値發送給服務器客戶端和服務器用DH算法進行3DES或AES算法的密鑰交換服務器接收到后綴表達式表達式后,進行解密,解密后計算明文的MD5值,和客戶端傳來的MD5進行比較,一致則調用MyDC.java的功能計算后綴表達式的值,把結果發送給客戶端客戶端顯示服務器發送過來的結果上傳測試結果截圖和碼云鏈接 遇到問題及解決方案
- 問題1解決方案:測試前應填入數據,再進行測試
- 問題2:出現java.net.SocketException: Connection reset,客戶端輸出文件出錯
- 問題2解決方案:該異常在客戶端和服務器端均有可能發生,引起該異常的原因有兩個,第一個就是如果一端的Socket被關閉(或主動關閉或者因為異常退出而引起的關閉),另一端仍發送數據,發送的第一個數據包引發該異常(Connect reset by peer)。另一個是一端退出,但退出時并未關閉該連接,另一端如果在從連接中讀數據則拋出該異常(Connection reset)。簡單的說就是在連接斷開后的讀和寫操作引起的。 在讀取信息時不應該關閉客戶端。
PSP
| 步驟 | 耗時(h) | 百分比 |
| 設計 | 2 | 20% |
| 代碼實現 | 5 | 50% |
| 測試 | 2 | 20% |
| 分析總結 | 1 | 10% |
實驗小結
本次實驗過程中出現了很多問題,反反復復折騰了幾天,不過在不斷地從書中網上查詢解決問題的過程中,收獲頗豐。其實不管是學習生活還是今后工作,有時候需要適當地逼一下自己,可能在某一方面投入90%精力但仍不見希望時,我們需要做的可能就是再努力10%。這應該是本學期最后一次實驗了,雖然Java實驗真的磨人,不過不論從知識的提升還是耐力的磨練,總算是有所收獲,還是挺感謝婁老師。希望自己以后也能屏住最后一口氣,撐住往前走。
?
轉載于:https://www.cnblogs.com/axyaxy/p/10946422.html
總結
以上是生活随笔為你收集整理的2018-2019-2 20175224 实验五《网络编程与安全》实验报告的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。