| 此次作業要求你改寫作業三的 TCP Server 程式,
加入 UDP Client 功能,以完成通訊要求。
此程式應先啟動好 TCP Concurrent Server 功能,然後建立一個 UDP Socket,先送一個 UDP Segment 給作業五的 UDP Server (IP 位址為 140.127.220.246, port = SERV_PORT + 2)。 此 Segment 帶有你的學號與 TCP server 的 port number,以空格字元隔開。 UDP Server 收到後,會進行下列步驟:
|

假設我們先將作業三的 server 程式 hw3serv.c 複製成為另一個 hw5cli.c。接下來
你可以用 Unix 下的 vi 或 GNOME 桌面下的 gedit 來編輯此程式。
事實上你要做的事情如下:
|
|
如果編譯沒問題,就可以執行你的這個 client 程式了。目前老師的 server IP 位址為 140.127.220.246。你可以在 client 程式中加適當的 output 訊息以瞭解 連線過程是否順利。如以下的執行範例: lhyen@m622:~/unpv13e/udpcliserv$ ./hw5cli15 140.127.220.246 sent [to 140.127.220.246, port 9879]: lhyen 9880 recv: id = lhyen, ip address = 140.127.220.246, #connections = 10 ip address match sent code 13 to server [Wed May 27 15:07:45 2015] connection 0 (from 140.127.220.246, port 37409) connection 0 recv: 587 [Wed May 27 15:07:45 2015] connection 1 (from 140.127.220.246, port 37410) connection 0 sent: 37409 587 [Wed May 27 15:07:45 2015] connection 2 (from 140.127.220.246, port 37411) [Wed May 27 15:07:45 2015] connection 3 (from 140.127.220.246, port 37412) connection 1 recv: 845 connection 1 sent: 37410 845 connection 1 recv: ok [Wed May 27 15:07:45 2015] connection 4 (from 140.127.220.246, port 37413) [Wed May 27 15:07:45 2015] connection 5 (from 140.127.220.246, port 37414) connection 2 recv: 857 [Wed May 27 15:07:45 2015] connection 1 closed connection 0 recv: ok connection 2 sent: 37411 857 [Wed May 27 15:07:45 2015] connection 6 (from 140.127.220.246, port 37415) [Wed May 27 15:07:45 2015] connection 0 closed connection 2 recv: ok connection 3 recv: 286 [Wed May 27 15:07:45 2015] connection 2 closed [Wed May 27 15:07:45 2015] connection 7 (from 140.127.220.246, port 37416) connection 3 sent: 37412 286 connection 3 recv: ok [Wed May 27 15:07:45 2015] connection 3 closed connection 4 recv: 641 connection 4 sent: 37413 641 connection 4 recv: ok [Wed May 27 15:07:45 2015] connection 4 closed connection 5 recv: 82 [Wed May 27 15:07:45 2015] connection 9 (from 140.127.220.246, port 37418) [Wed May 27 15:07:45 2015] connection 8 (from 140.127.220.246, port 37417) connection 5 sent: 37414 82 connection 5 recv: ok connection 6 recv: 90 [Wed May 27 15:07:45 2015] connection 5 closed connection 6 sent: 37415 90 connection 7 recv: 301 connection 6 recv: ok connection 7 sent: 37416 301 [Wed May 27 15:07:45 2015] connection 6 closed connection 7 recv: ok connection 8 recv: 206 [Wed May 27 15:07:45 2015] connection 7 closed connection 8 sent: 37417 206 connection 8 recv: ok connection 9 recv: 869 [Wed May 27 15:07:45 2015] connection 8 closed connection 9 sent: 37418 869 connection 9 recv: ok [Wed May 27 15:07:45 2015] connection 9 closed recvfrom [140.127.220.246, port 9879]: ok lhyen@m622:~/unpv13e/udpcliserv$server 程式會記錄連線的時間, IP 位址, port號碼等訊息,也會記錄收到的資料。為了確認你的 程式沒有問題,你應該先下載安裝 server 程式,自行在本地端測試成功之後, 再正式與此作業的 Server 連線。我將以 server 程式的連線記錄檔來作為程式是否撰寫成功與否的依據。 |
與之前的作業不同,此次你的 UDP Clinet 程式會啟動 TCP Server,因此如果你執行完你的程式後
,在很短的時間內又再度執行一次,很可能會看到下列訊息:
lhyen@m622:~/unpv13e/udpcliserv$ ./hw5cli15 140.127.220.246 bind error: Address already in use 這是因為 TCP Server 還在 TIME_WAIT 狀態 (參考課本 Fig. 2.4)。你所要做的只是稍微等一下。 提醒各位:在此作業的 Server 程式中,TCP Client 送出來的資料最後均有 '\n' 字元,它也 期待各位的 TCP Server 送給它的資料也是如此。但是我們的 UDP Server 送收資料最後 均沒有 '\n' 字元。 另外,還是要記得 Read 和 Recvfrom 這類函數從 socket 讀資料進來時, 並不會自動在資料最後面加 '\0'。 所以如果要呼叫字串相關函如 strlen, strcmp 對此資料作運算時, 記得要自行在讀進資料最後面加上 '\0' 才會正確。 還有,對於 value-result argument,一定要在呼叫函數前正確設定它的值,否則得不到正確的結果。 在下面的程式碼中,如果拿掉第一列的assignment敘述,就跑不出正確的結果。
另外,當 UDP Server 傳送給你學號、你的機器的 IP 位址、以及 n 值時,請先確認學號與 IP 位址與你認知的是否一致。請你自行用 getsockname 取得本身 IPv4 位址, 若此位址與老師的 UDP Server 偵測到的你的機器的 IPv4 位址不同,則表示你的機器可能位於 NAT 內部,此時老師的程式就無法連到你的 TCP server 的 port 了 (無法穿透 NAT)。此時記得用 UDP 回傳 "13" 以外的狀態代碼,如 "21" (但避免傳 "0")。此次上傳作業即算失敗,必須重來。 同學常見的問題是 local 測試 ok 但連上老師伺服器就不行,這就可能是 NAT 造成的問題。解決之道是將你寫好 local 測試 ok 的程式帶到系上電腦教室重新編譯執行(記得教科書中的程式原始檔也要全部安裝設定好 才能編譯你的程式喔)。不過目前系上電腦教室有部份電腦亦是使用私有 IP位址,此種電腦 也不能成功執行,所以要先確認所使用電腦IP位址是140.127.*.*這種的才行喔。 最後,如果你的 UDP 訊息與其他使用者的 UDP 訊息混在一起,UDP Server 會回傳 "conflict"。這也算上傳作業失敗,必須重來一次。 |
Maintained by Li-Hsing Yen.