---
# System prepended metadata

title: net w3
tags: [network]

---

# 網路程式設計 w3

## 第一題 使用wireshark抓封包

- 請使用wireshark抓當telnet echo server時，分別鍵入ncyu並按下enter鍵結束，請截圖顯示此過程的所有的tcp封包，並統計共有幾個。
    ![image](https://hackmd.io/_uploads/SJiDvddpa.png)
    
    - 封包總共顯示23個
        - TCP三次交握：3個
            ![image](https://hackmd.io/_uploads/rJp6Y__Tp.png)
        - n訊息傳送  ：4個
            ![image](https://hackmd.io/_uploads/SJjRF__pT.png)
        - c訊息傳送  ：4個
            ![image](https://hackmd.io/_uploads/BkLkcdOTa.png)
        - y訊息傳送  ：4個
            ![image](https://hackmd.io/_uploads/B1fx9OO6a.png)
        - u訊息傳送  ：4個
            ![image](https://hackmd.io/_uploads/SJhgqOdT6.png)
        - TCP四次揮手：4個
            ![image](https://hackmd.io/_uploads/rJEW5OOpp.png)
## 第二題 5種服務的示範程式
- 程式碼

```C++=
#include <iostream>
#include <cstring>
#include <iomanip>
#include <winsock.h>
#define MAX_LINE 1024
using namespace std;

void printService();
int opition(int);
int main(int argc,char** argv){
    system("chcp 65001");
    int port = 0;
    int resvByte = 1;
    // window socket set up
    WSADATA wsadata;
    WSAStartup(0x101,(LPWSADATA) &wsadata);

    // Open a TCP socket
    SOCKET sd;   
    sd=socket(AF_INET, SOCK_STREAM, 0);

    // Server information 
    struct sockaddr_in serv;
    serv.sin_family       = AF_INET;
    serv.sin_addr.s_addr  = inet_addr("127.0.0.1");
    

    // Service print
    printService();
    cin>>port;
    port = opition(port);
    serv.sin_port= htons(port);



    // message
    string mSend;
    char   mRecv[MAX_LINE];
    connect(sd, (LPSOCKADDR) &serv, sizeof(serv));
    switch (port)
    {
        case 7: //Echo Service
            cout<<"Enter your message:\n";
            cin.ignore();
            getline(cin, mSend);
            send(sd, mSend.c_str(), mSend.size()+1, 0);
            resvByte = recv(sd, mRecv, MAX_LINE, 0);
            break;
        case 9: //Discard Service
            cout<<"Enter your message:\n";
            cin.ignore();
            getline(cin, mSend);
            send(sd, mSend.c_str(), mSend.size()+1, 0);
            break;
        case 13: //Daytime Service
            resvByte = recv(sd, mRecv, MAX_LINE, 0);
            break;
        case 17: //Quote Service
            resvByte = recv(sd, mRecv, MAX_LINE, 0);
            break;
        case 19: //Char Generator Service
            resvByte = recv(sd, mRecv, MAX_LINE, 0);
            break;
        default:
            cerr<<"Invalid Number!\n";
            exit(1);
            break;
    }

    //print result
    cout<<"______________執行結果______________\n";

    
    cout<<"[傳送內容]\n"<< mSend<<endl;
    cout<<"[傳送內容長度]"<< mSend.size()+1<<" Bytes"<<endl;
    cout<<"____________________________________\n";
    cout<<"[回應內容]\n"<< string(mRecv) << endl;
    cout<<"[回應內容長度]"<<resvByte<<" Bytes"<<endl;
    
    closesocket(sd);
    WSACleanup();
    system("pause");
    return 0;
}
void printService(){
    cout <<         "____________________________________\n";
    cout <<         "|    1. Echo       回應模式          |\n" ;
    cout <<         "|    2. Discard    丟棄模式          |\n" ;
    cout <<         "|    3. Daytime    日期與時間模式     |\n";
    cout <<         "|    4. QUOTE      每日一句          |\n";
    cout <<         "|    5. CHARGEN    字元產生器        |\n";
    cout <<         "|___________________________________|\n";
}



int opition(int n){
    switch (n)
    {
        case 1:
            return 7;
            break;
        case 2:
            return 9;
            break;
        case 3:
            return 13;
            break;
        case 4:
            return 17;
            break;
        case 5:
            return 19;
            break;
        default:
            cerr<<"Invalid Number!";
            exit(1);
            break;
    }
}
```
- 執行結果
    - Echo
        ![image](https://hackmd.io/_uploads/r13-gFdTT.png)
    - Discard
        ![image](https://hackmd.io/_uploads/rymPeKdpp.png)
    - QUOTE
        ![image](https://hackmd.io/_uploads/r1FFlF_6T.png)
        - ps. 出現亂碼是BIG-5與UTF-8編碼問題(我這邊預設是UTF-8，所以導致亂碼)
    - QUOTE
        ![image](https://hackmd.io/_uploads/rk10xF_pp.png)
    - CHARGEN
        ![image](https://hackmd.io/_uploads/B1dxbK_Tp.png)
- 特例討論
    - 本程式碼在選取選單時不能超過1~5，若超過程式會報錯，並傳送錯誤訊息
        ![image](https://hackmd.io/_uploads/r1nLZYdpT.png)
## 第三題：心得
這周玩telnet好好玩，之前計算機網路只知道他是文字互動功能，可以實現遠端控制，這次有機會玩他。BTW,我之前有聽過telnet未加密過，容易被竊聽，所以現今都用ssh加密連線。

作業的部分，我感覺我對抓封包越來越熟悉了，但程式作業中文字串的編碼問題真的好麻煩，我日期那邊有產生亂碼(我猜是Big-5編碼)，後來查好久都沒有很實際的方法(我的consloe使用UTF-8顯示)，希望這周有電神同學有實際方式實踐orz。


## 3/12後記
後來有用Python寫，發現剛好可以解決Big-5編碼問題(但我C++還是無解)，Python Socket在傳輸時是用Byte這個資料型態傳送，因此只要調整編碼格式就可以順利解決
```python=
import socket
import os
def printMeun():
    print("_____________________________________")
    print("|    1. Echo       回應模式          |")
    print("|    2. Discard    丟棄模式          |")
    print("|    3. Daytime    日期與時間模式     |")
    print("|    4. QUOTE      每日一句          |")
    print("|    5. CHARGEN    字元產生器        |")
    print("_____________________________________")

def servicePort(service:int) -> int:
    match service:
        case 1:
            return 7
        case 2:
            return 9
        case 3:
            return 13
        case 4:
            return 17
        case 5:
            return 19
        case _:#Default
            print("Please enter 1~5")
            exit
# Socket set up
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
HOST = "127.0.0.1"
PORT = -1

sendData = ""
recvData = ""

printMeun()
PORT = servicePort(int(input()))
s.connect((HOST, PORT))
if PORT == 7:
    sendData = input("Please enter message u want to send：")
    s.send(sendData.encode()) #Send data by byte
    recvData = s.recv(1024).decode()
if PORT == 9:
    sendData = input("Please enter message u want to send：")
    s.send(sendData.encode()) #Send data by byte
if PORT == 13 or  PORT == 17 or PORT == 19:
    recvData = s.recv(1024).decode('big5')

print("______________執行結果______________")

print(f"[傳送內容]：   {sendData}")
print(f"[傳送內容長度] {len(sendData) + 1} Bytes")


print("____________________________________")
print(f"[回應內容]：   {recvData}")
print(f"[回應內容長度] {len(recvData) + 1} Bytes")

os.system("pause")
```

- 執行結果
![image](https://hackmd.io/_uploads/B1NTvnapa.png)
![image](https://hackmd.io/_uploads/SknAwhaTp.png)
![image](https://hackmd.io/_uploads/S1xgunapa.png)
![image](https://hackmd.io/_uploads/r1hlOhT6p.png)
![image](https://hackmd.io/_uploads/Hycb_36ap.png)
