# 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