# 網路程式設計 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)