---
# System prepended metadata

title: HW1-socket programming

---

#  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.














    
    
    
  
    










   



