# 2019q1 Homework5 (daemon) contributed by < `njjack` > #### 問題:輸出亂碼 參考作業說明 [daemon](https://hackmd.io/s/r14Qu9hYV),按步驟測試 1. 載入編譯好的 module `fastecho` 2. `$ telnet localhost 12345` 3. 輸入任意字串,回傳結果除了 input 之外還有亂碼 ![](https://i.imgur.com/6vInToT.png) 檢視 printk 印出的 `buf` 內容,顯然不只有 input 內容 ![](https://i.imgur.com/cNU01ZE.png) :::danger 文字訊息不要用螢幕截圖的方式呈現,不然日後很難檢索。 :notes: jserv ::: 印出 `buf` 在 呼叫 `get_request` 前後的內容,比較兩者發現有相同的"亂碼",因此亂碼和傳輸過程無關,只是記憶體未經初始化的原有內容。暫時先藉由設置結束符解決輸出亂碼的問題 ```clike length = kernel_recvmsg(sock, &msg, &vec, size, size, msg.msg_flags); buf[length]='\0'; ``` [`kernel_recvmsg`](https://www.kernel.org/doc/htmldocs/networking/API-kernel-recvmsg.html) : The returned value is the total number of bytes received, or an error. ![](https://i.imgur.com/27wtGJa.png) 乍看解決了輸出的問題,但印出的 `buf` 結果其實還包含了多餘的換行,且若印出 `length` 的值,可以發現實際 receive 的 byte 數比 input 的 byte 數還要多 2 #### 問題:重新載入 module 錯誤 結束 telnet 連線並移除 module `fastecho` ,重新再載入 module `fastecho` 時會失敗 ``` $ sudo rmmod fastecho.ko rmmod: ERROR: Module fastecho is not currently loaded ``` 嘗試更改預設 port 值 `DEFAULT_PORT`,發現編譯後的 module 可以成功載入,猜測是沒有正常釋放 port 實際觀察發現 port 被佔用但沒有列出 process 的 pid ,狀態顯示為 `CLOSE_WAIT` ``` $ sudo netstat -p | grep 12345 tcp 0 0 localhost:12345 localhost:36628 CLOSE_WAIT - ``` 參考[浅谈CLOSE_WAIT](https://blog.huoding.com/2016/01/19/488),被動關閉連線的一方(在此為server)卡在 `CLOSE_WAIT` 狀態,其中一個原因在於 server 沒有即時送出 FIN ,而 client 等不到回應直接結束 ![](https://i.imgur.com/YUJYDYw.png) (圖取自同篇文章) :::info 交叉參照 [重新實現reuseport邏輯,實現一致性hash](https://blog.csdn.net/dog250/article/details/89268404) :notes: jserv ::: 原程式碼函式 `echo_server_worker` 持續呼叫 `get_request` 和 `send_request` 來接收傳遞訊息 嘗試將跳出 while 迴圈後最後一次 `get_request` 和 `send_request` 的呼叫註解掉 ```clike static int echo_server_worker(void *arg) { ... while (!kthread_should_stop()) { res = get_request(sock, buf, BUF_SIZE - 1); ... res = send_request(sock, buf, strlen(buf)); ... } //res = get_request(sock, buf, BUF_SIZE - 1); //res = send_request(sock, buf, strlen(buf)); kernel_sock_shutdown(sock, SHUT_RDWR); sock_release(sock); kfree(buf); return 0; } ``` 可以觀察到 client 中斷連線後狀態來到 `TIME_WAIT` ,而 server 已經 closed, 依TCP 關閉連線程序此為正常結果 ``` $ netstat | grep :12344 tcp 0 0 localhost:52996 localhost:12344 TIME_WAIT ``` (待補)client 卡在 FIN_WAIT_1 而不是 FIN_WAIT_2