---
# System prepended metadata

title: net w8
tags: [network]

---

# 網路程式設計 Week8

## LAB1: 以UDP來一送一收
- 程式碼
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on 12345");


            int n = recvfrom(
                sd,
                DATA,100,0,
                (LPSOCKADDR) &client, &len_client
            );
            printf("recv:%s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",1234

        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

        serverSocket.bind((HOST,PORT))
        print("UDP Server up and listening...")

        while True:
            data, ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {data.decode()}")
            print("===============================")
        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include <stdio.h>
        #include <winsock.h>

        char DATA[100] = "\\C is very hard!!!!!!/";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Client socket => ready to connect to server

                note nate we use UDP, so the socket of client is sock datagram
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);


            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;

            /*
                Start to send data to server
            */
            int n = sendto(
                sd,
                DATA, strlen(DATA),0,
                (LPSOCKADDR) &serv, sizeof(serv)
            );
            printf("Send: %s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        DATA = "I Love Python!!!!"
        HOST,PORT = "127.0.0.1",1234

        clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        clientSocket.sendto(DATA.encode(),(HOST,PORT))

        print(f"Message send: {DATA}")
        ```
        :::
- 實驗結果
    - 有CS架構下，UDP程式只會有一個封包
        - Wireshark抓取結果
            ![image](https://hackmd.io/_uploads/BJAsN_Vb0.png)
    - 無CS架構下，UDP程式扔會傳送一個封包
         - Wireshark抓取結果
            ![image](https://hackmd.io/_uploads/rJD1rO4W0.png)
            - Wait... 理論上不會產生ICMP吧
                - ICMP是網際網路控制訊息協定，幾乎每個人的網路封包都有，用以表示網路狀態，這邊產生原因是找不到目的地，代表我沒有Server
    - 在TCP程式無Server下，會因無法建立連線而傳送失敗
        - Wireshark抓取結果
            ![image](https://hackmd.io/_uploads/r10mUdVb0.png)
- 程式執行解果
    ![image](https://github.com/kevin0920911/NetworkGIF/blob/main/w8/GIF/Lab1.gif?raw=true)

## LAB2: 改為一(程式)送二(程式)收
- 程式碼
    - 說明
        - 為了達到1送10我做了以下改變
            - Server在listen前，我先請使用者input port
            - Client data創建了10筆
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            int port;
            printf("Input the port number u want to recv: ");
            scanf ("%d",&port); 
            serv.sin_port = htons(port);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on %d",port);

            for (int i=0;i<10;i++){
                int n = recvfrom(
                    sd,
                    DATA,100,0,
                    (LPSOCKADDR) &client, &len_client
                );
                printf("recv:%s (%d)\n",DATA,n);
            }
            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",int(input("Enter port: "))
        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        serverSocket.bind((HOST,PORT))

        while True:
            message ,ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {message.decode()}")
            print("===============================")

        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            int port;
            printf("Input the port number u want to recv: ");
            scanf ("%d",&port); 
            serv.sin_port = htons(port);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on %d",port);

            for (int i=0;i<10;i++){
                int n = recvfrom(
                    sd,
                    DATA,100,0,
                    (LPSOCKADDR) &client, &len_client
                );
                printf("recv:%s (%d)\n",DATA,n);
            }
            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",int(input("Enter port: "))
        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        serverSocket.bind((HOST,PORT))

        while True:
            message ,ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {message.decode()}")
            print("===============================")
        ```
        :::
- 實驗結果
    - 對於socket的數量
        - TCP是connect oriented，所以需要10個socket
        - UDP是connectless oriented，所以只要一個socket即可
    - 改為1 to 10
        - Server在listen前，我先請使用者input port
- 執行結果
    ![image](https://github.com/kevin0920911/NetworkGIF/blob/main/w8/GIF/2.gif?raw=true)
## LAB3: 改為二(程式)送一(程式)收，並顯示來源端資訊
- 程式碼
    - 說明
        - 為了達到10送1我做了以下改變
            - Client再傳送前要輸入port
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            int port;
            printf("Input the port number u want to recv: ");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on %d",port);

            for (int i=0;i<10;i++){
                int n = recvfrom(
                    sd,
                    DATA,100,0,
                    (LPSOCKADDR) &client, &len_client
                );
                printf("recv:%s (%d)\n",DATA,n);
            }
            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",1234

        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

        serverSocket.bind((HOST,PORT))
        print("UDP Server up and listening...")

        while True:
            data, ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {data.decode()}")
            print("===============================")
        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include <stdio.h>
        #include <winsock.h>

        char DATA[100] = "\\C is very hard!!!!!!/";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Client socket => ready to connect to server

                note nate we use UDP, so the socket of client is sock datagram
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);


            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;

            /*
                Start to send data to server
            */
            int n = sendto(
                sd,
                DATA, strlen(DATA),0,
                (LPSOCKADDR) &serv, sizeof(serv)
            );
            printf("Send: %s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        DATA = [
            "Hello, World!",
            "How are you today?",
            "I'm learning programming.",
            "Python is my favorite language.",
            "Today is a beautiful day.",
            "Coding is fun and challenging.",
            "I enjoy solving problems.",
            "Reading books is a good habit.",
            "Practice makes perfect.",
            "Never stop learning."
        ]
        HOST,PORT = "127.0.0.1",1234
        channel = int(input("Enter channel(1-10): "))

        clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        clientSocket.sendto(DATA[channel].encode(),(HOST,PORT))
        print(f"Message send: {DATA[channel]}")

        ```
        :::
- 實驗結果
    - 以Socket數量來說
        - TCP接收端通常需要10個
        - UDP只需要1個就可以了
    - 改為10 to 1
        - 只要開10個終端機然後傳送到server就好
- 執行結果
    ![image](https://github.com/kevin0920911/NetworkGIF/blob/main/w8/GIF/Lab3.gif?raw=true)
## LAB4: UDP實作變化：當傳送對象是固定對象時
- 程式碼
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on 12345");


            int n = recvfrom(
                sd,
                DATA,100,0,
                (LPSOCKADDR) &client, &len_client
            );
            printf("recv:%s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",1234

        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

        serverSocket.bind((HOST,PORT))
        print("UDP Server up and listening...")

        while True:
            data, ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {data.decode()}")
            print("===============================")
        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include <stdio.h>
        #include <winsock.h>

        char DATA[100] = "\\C is very hard!!!!!!/";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Client socket => ready to connect to server

                note nate we use UDP, so the socket of client is sock datagram
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);


            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;

            /*
                Start to send data to server
            */
           connect(sd,(LPSOCKADDR) &serv,sizeof(serv));
            int n = send(
                sd,
                DATA, strlen(DATA),0
            );
            printf("Send: %s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket
        import time

        HOST,PORT = "127.0.0.1",1234
        DATA = "I don't know what to send"
        sd = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        sd.connect((HOST,PORT))

        while True:
            rate = int(input("Enter rate: "))
            sendTime = 1/rate
            for i in range(10):
                sd.send(DATA.encode())
                print(f"Message send: {DATA}")
                time.sleep(sendTime)
        ```
        :::
- 實驗結果
    - connect的影響
        - Wireshark分析
            ![image](https://hackmd.io/_uploads/HkU1lYV-A.png)
        - 其實結果和LAB1一樣，只有一個封包，不會和TCP程式一樣要建立連線
- 執行結果
    ![image](https://hackmd.io/_uploads/SJ689t4b0.png)

## LAB5: UDP實作變化：當傳送端想用固定port時
- 程式碼
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;


            /*
                Client information tmp
            */
            struct sockaddr_in client;
            int len_client = sizeof(client);
            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on 12345");


            int n = recvfrom(
                sd,
                DATA,100,0,
                (LPSOCKADDR) &client, &len_client
            );
            printf("recv:%s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",1234

        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

        serverSocket.bind((HOST,PORT))
        print("UDP Server up and listening...")

        while True:
            data, ip = serverSocket.recvfrom(1024)
            print(f"Client IP: {ip}")
            print(f"Message: {data.decode()}")
            print("===============================")
        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include <stdio.h>
        #include <winsock.h>

        char DATA[100] = "\\C is very hard!!!!!!/";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Client socket => ready to connect to server

                note nate we use UDP, so the socket of client is sock datagram
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);


            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;
            /*
                client information
                    IP: 127.0.0.1
                    Port: 1234
                    sinfamily: IPV4
            */
            struct sockaddr_in clint;
            clint.sin_addr.s_addr = inet_addr("127.0.0.1");
            clint.sin_port = htons(1234);
            clint.sin_family = AF_INET;
            /*
                Start to send data to server
            */
           bind(sd,(struct sockaddr*) &clint, sizeof(clint));
           connect(sd,(LPSOCKADDR) &serv,sizeof(serv));
            int n = send(
                sd,
                DATA, strlen(DATA),0
            );
            printf("Send: %s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        DATA = "I Love Python!!!!"
        HOST,PORT = "127.0.0.1",1234
        IP,CLIPORT = "127.0.0.1",3456

        clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        clientSocket.bind((IP,CLIPORT))
        clientSocket.connect((HOST,PORT))
        clientSocket.send(DATA.encode())

        print(f"Message send: {DATA}")
        ```
        :::
- 實驗結果
    - Client Bind之後，程式可執行成功，且server接收時確實能產生對應的port
        - 使用python bind的結果
            ![image](https://hackmd.io/_uploads/rJkZQYNb0.png)
            - 可以發現我的port就是我設定的
- 執行結果
    ![image](https://hackmd.io/_uploads/rJZ29YNZA.png)
## LAB6: UDP實作變化：當傳接送端不關心傳送來源時
- 程式碼
    - Server
        :::spoiler C
        ```C=
        #include<stdio.h>
        #include<winsock.h>
        char DATA[100] = "";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;

            /*
                Server sock binding
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);
            bind(sd,(LPSOCKADDR)&serv,sizeof(serv));
            printf("Ready to recv on 12345");

            while (1){
                int n = recv(
                    sd,
                    DATA,100,0
                );
                printf("recv:%s (%d)\n",DATA,n);
            }


            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        HOST,PORT = "127.0.0.1",1234

        serverSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

        serverSocket.bind((HOST,PORT))
        print("UDP Server up and listening...")

        while True:
            data= serverSocket.recv(1024)
            print(f"Message: {data.decode()}")
            print("===============================")
        ```
        :::
    - Client
        :::spoiler C
        ```C=
        #include <stdio.h>
        #include <winsock.h>

        char DATA[100] = "\\C is very hard!!!!!!/";
        int main(){
            /*
                Register winsock
            */
            WSADATA wsadata;
            WSAStartup(0x101,(LPWSADATA) &wsadata);

            /*
                Client socket => ready to connect to server

                note nate we use UDP, so the socket of client is sock datagram
            */
            SOCKET sd = socket(AF_INET,SOCK_DGRAM,0);


            /*
                Server information
                    IP: 127.0.0.1
                    Port: 12345
                    sinfamily: IPV4
            */
            struct sockaddr_in serv;
            serv.sin_addr.s_addr = inet_addr("127.0.0.1");
            serv.sin_port = htons(12345);
            serv.sin_family = AF_INET;
            /*
                client information
                    IP: 127.0.0.1
                    Port: 1234
                    sinfamily: IPV4
            */
            struct sockaddr_in clint;
            clint.sin_addr.s_addr = inet_addr("127.0.0.1");
            clint.sin_port = htons(1234);
            clint.sin_family = AF_INET;
            /*
                Start to send data to server
            */
           bind(sd,(struct sockaddr*) &clint, sizeof(clint));
           connect(sd,(LPSOCKADDR) &serv,sizeof(serv));
            int n = send(
                sd,
                DATA, strlen(DATA),0
            );
            printf("Send: %s (%d)\n",DATA,n);

            closesocket(sd);
            WSACleanup();
            system("pause");
            return 0;
        }
        ```
        :::
        :::spoiler Python
        ```python=
        import socket

        DATA = "I Love Python!!!!"
        HOST,PORT = "127.0.0.1",1234
        IP,CLIPORT = "127.0.0.1",3456

        clientSocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
        clientSocket.bind((IP,CLIPORT))
        clientSocket.connect((HOST,PORT))
        clientSocket.send(DATA.encode())

        print(f"Message send: {DATA}")
        ```
        :::
- 實驗結果
    - 使用recv後我完全不用在宣告一個IP的structure，更有彈性，~~感覺也更隨便~~
- 執行結果
    ![image](https://hackmd.io/_uploads/rJDliFEZ0.png)
## 心得
這周學了UDP程式設計，感覺他比TCP更加自由，畢竟不用連線，所以socket可以亂亂用，但也有一些大缺點，例如像封包可能遺失等，感覺可以用確認碼等技巧補足。

作業的部分，我1~6嘗試用C與python寫，尤其是寫完C之後寫Python有一種快速通關的感覺，我最愛Python了0.0。

BTW, 上周的netcat好好玩，我之前在linux用也頂多只有連線到對方主機而已，沒想到window也有，而且功能比我想像的豐富，還可以聆聽封包，難怪稱為網路瑞士刀，因為功能多多。

## 附錄
[全部程式碼在這](https://github.com/kevin0920911/NetworkGIF/tree/main/w8)