# Socket Programming Report --- ## 學生:B1105142 李旼學 ## 授課老師: 蔡仁勝教授 ___ ## 報告內容 ## 一.實驗目的: 使用socket programming 模擬 client server間的 TCP connection , 並利用wireshark分析封包 ## 二.實驗材料: vscode,wireshark ## 三.程式碼: ▾以下是server的socket ``` import socket import random server_name = "Server of Nuk" server_ip = "127.0.0.1" server_port = 2000 ''' 建立server的名字 以及所對應的IP以及Port ''' server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((server_ip, server_port)) server_socket.listen(0) print(f"listening on {server_ip}:{server_port}") ''' 建立server的socket 採用IPV4以及TCP的服務 並將一開始建立的IP以及Port植入socket 接下來便開始監聽是否有人呼叫server ''' while True: connection, client_address = server_socket.accept() print("Connection from", client_address) ''' 若有client來建立連線 則接受連線後 印出client address ''' data = connection.recv(1024) if not data: break client_name, client_number = data.decode().split(',') ''' 此時根據題目要求 client會在此時傳送資料 內含它的名字以及所輸入的number server此時接收到這個封包 並將資料extract出來 ''' if 1 <= int(client_number) <= 100: print(f"Client_name: {client_name}") print(f"Server_name: {server_name}") server_number = random.randint(1, 100) sum = int(client_number) + server_number print(f"Client_number: {client_number}") print(f"Server_number: {server_number}") print(f"Sum: {sum}") server_reply = f"{server_name},{server_number}" connection.send(server_reply.encode()) else: print("Client number is not in the range 1 to 100. Closing connection.") ''' 接下來根據題目要求 如果client_number在1到100之間 就印出client_name跟server_name 然後server在1到100間隨機選一數 與client_number相加 接著印出 client_number Server_number跟兩者的sum 接著server回傳一個reply給client 裡面包含了server_name 以及Server_number 但如果client_number不在範圍內 就直接close connection ''' connection.close() ``` ▾以下是client的socket ``` import socket client_name = "Client of Louis" server_ip = "127.0.0.1" server_port = 2000 ''' 建立client的名字 以及要連結的server Ip 跟 Port ''' client_number=input("Enter the number between 1 and 100:") client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((server_ip,server_port)) ''' 建立client的socket 採用IPV4以及TCP的服務 接著輸入1到100之間的數字後 與server建立連線 ''' client_send = f"{client_name},{client_number}" client_socket.send(client_send.encode()) ''' 接著建立封包內含client_name跟client_number encode後傳送給server ''' data= client_socket.recv(1024) server_name, server_number = data.decode().split(',') ''' 收到server回傳的封包 內含server_name跟server_number 然後將其extract出來 ''' sum = int(client_number) + int(server_number) print(f"Client Name: {client_name}") print(f"Server Name: {server_name}") print(f"Client Number: {client_number}") print(f"Server Number: {server_number}") print(f"Sum: {sum}") ''' 印出上述5個設定的值 ''' client_socket.close() ``` 程式碼的撰寫想法附在程式中,其實只要了解TCP連線的步驟,以及熟悉python寫socket時的語法,就能輕鬆實現這次的實驗. ## 四.實驗結果: case1: 當client number介於1到100之間時 ▾以下是server在vscode上的結果 ![螢幕擷取畫面 2023-11-20 230102](https://hackmd.io/_uploads/rJtWrxYEa.png) ▾以下是client在vscode上的結果 ![螢幕擷取畫面 2023-11-20 230127](https://hackmd.io/_uploads/SkGnBlKNp.png) 由結果可得知,此client server的行為跟報告要求相同,而且可看出此時cilent的port為59765. case2:當client number不在1到100之間時 ▾以下是server在vscode上的結果 ![螢幕擷取畫面 2023-11-20 230933](https://hackmd.io/_uploads/SJlTUgYEp.png) ▾以下是client在vscode上的結果 ![螢幕擷取畫面 2023-11-20 230905](https://hackmd.io/_uploads/By90Ugt4a.png) 可看出當client number不在1到100之間時,server會直接結束連線,而client 因為收不到server的封包而error, 接著觀察此時client的port變成64071, 與前一次不同,是因為執行了兩次不同的連線,而cilent使用了dynamic port,也 會相應的改變. ## 五.實驗討論: 有了以上的結果後,接下來就是使用wireshark,分析擷取到的封包,來進行進一步的解讀.先觀察server(port 2000)擷取到的封包,以下為wireshark的結果. ![螢幕擷取畫面 2023-11-20 232455](https://hackmd.io/_uploads/Hk1PqxFE6.png) 以下為在client(port 59765)擷取到的封包 ![螢幕擷取畫面 2023-11-20 235450](https://hackmd.io/_uploads/SJ6LbbKNp.png) 首先先分析封包的流程,一開始由client發送SYN要求連線,server則回覆一個SYN ACK,client此時在送一個ACK表示收到回覆,建立起一個 3-way hand-shaking.接下來cilent傳送一個含有其名字跟number的封包給server,也就是PSH ACK這個封包,server收到後回覆一個ACK.接著server回傳其名字跟number給client,就是server端的PSH ACK封包,client收到後回復一個ACK.接著server發送FIN ACK請求終止連線,client收到後回覆一個ACK,接著也發送一個FIN ACK請求終止連線,server回覆一個ACK後,這次的流程就結束了. 接下來分析上課所說過的seq以及ack,我將其流程畫成以下的圖形. ![S__24920111](https://hackmd.io/_uploads/BkfLsbtNT.jpg) 當client傳送pkt時,其len為19,所以server回傳ack20,表示20前的byte都收到了.當server傳送pkt時,其len為16,所以cilent回傳seq20 ack17,因為前面傳送了20bytes,ack17則表示17以前的都收到了. ![螢幕擷取畫面 2023-11-21 014235](https://hackmd.io/_uploads/rkooqGtN6.png) 探究封包中的內容,也可以發現上課所說的window以及checksum.