通訊機制示意圖
本單元的目的是為接下來的網路通訊動作做準備,包括以程式自動取得本機的IP,不必每次都要離開程式去查本機電腦的IP。其次也經過傳輸小型的影像檔案,體驗一下網路通訊常用的『交握』(Hand Shaking)動作,譬如傳檔案時不能直接就傳資料,必須先給個檔案資訊,如檔名可以讓對方知道收到檔案之後必須怎麼開啟,檔案大小則可能與要用幾個封包(分幾次)傳遞有關。本範例中只示範檔名的交握動作,讓接收端知道收到的影像是哪種格式,如JPG或GIF,以便正確開啟影像。

IP v4 與 IP v6
IP是電腦在網路世界定址的方式,多數人習慣使用的的IP大概是這樣的:192.168.1.1
由四個0~255的數字組成,中間用小數點分隔,事實上在電腦內部就是四個 Byte 組成的一個數字。這種IP稱為IP v4也就是第四版的IP定義,理論上這樣的數字最大可以包括2的32次方個IP,約40多億個!
目前IP v4的定義方式已經不敷使用,所以已有新版的 IP v6 開始平行使用,它們是由八組四個位數以冒號分隔的16進位數字組成,共有128個位元(8個16位元的整數),可以定義的IP數目當然非常的大,應該夠未來幾十年使用了!

取得本機IP
本範例基本上延伸自上一個UDP即時通程式,請先建立專案加入以下程式碼:

一般人可能不知道,一部電腦事實上是允許同時有多個IP的,當然也可以同時擁有IP v4與 IP v6的IP,所以用程式取得本機IP時資料結構上是取得一個IP的『陣列』,當然一般電腦實際使用的只會有一個IP,所以上面的 LocalIP程式就是取出第一個 InterNetwork型態的IP,也就是你的電腦的IP v4版的IP了!相對的,IP v6的IP將會是 InterNetworkV6。我們配合Form_Load事件就可以將本機 IP顯示於表單的標題上,大概像這樣:

當然這只是測試 localIP功能的程式碼,證實功能無誤之後可以刪除 Form_Load程式,在啟動監聽時再呼叫使用 localIP。

建立表單介面

請修改表單介面如上圖,因為本範例必須有選檔案的動作,也請加入一個 OpenFileDialog物件。
基本上這還是一個雙向的程式,可以接收也可以傳送影像,上面的 Label5是預備顯示對方傳來影像的檔名之用,下方的方塊是一個預備顯示影像用的PictureBox物件,SizeMode設為AutoSize(自動縮放到原圖大小)。

匯入功能、啟動接收與關閉監聽的程式與前一單元完全相同不需修改






傳送影像的程式

傳送影像當然是從使用OpenFileDialog物件選擇影像檔案開始,選出來的檔名(FileName)事實上會是完整的冗長路徑名稱,像:C:\A\B\狗狗.jpg,但是用SafeFileName就只有"狗狗.jpg"了!我們只需要將這個檔名傳過去就好。
至於用到的 Send 副程式是取得對方的IP與Port在臨時建立一個UDP物件再將資料傳過去。與即時通單元不同的是我們不直接使用監聽的同一UDP物件,原因只是盡量避免衝突。
但是這樣並沒有將實際檔案傳過去,我們必須等對方確定收到檔名,並給我們確認訊息("OK")之後才會正式傳檔案,這些後續工作就交給監聽副程式去處理了!

監聽副程式

前面收到網路訊息(Byte陣列)的程式與前一單元大致相同,只有監聽端點改成本機IP(localIP),不再用"127.0.0.1"。
收到訊息之後先用訊號長度判斷是檔名或圖檔資料?小於255時『應該』是檔名或確認訊息"OK",大於255則『應該』是圖檔本身的資料。這是一個很偷懶的判斷方式,當然是為了先不要用太複雜的判斷式困擾剛剛入門的各位同學啦!
專業程式應該會在資料最前面幾個 Byte加個字頭指稱這是訊息、檔名或圖資!
整個通訊流程是這樣的:

步驟一:傳送端先選擇要傳輸的影像檔案,取出檔名(去掉目錄路徑)轉為Byte陣列再 Send出去(Button2)。
步驟二:接收端接到檔名顯示於Label5,回傳"OK"。(Listen程式)
步驟三:傳送端收到"OK"訊息後讀取影像檔為Byte陣列並傳送出去。(Listen程式)
步驟四:接收端收到影像後存到實體檔案,再載入到PictureBox顯示影像。(Listen程式)
在此必須先傳檔名的原因是:圖檔有很多格式(JPG、GIF等),不知道檔名時會無法正確讀取影像到表單。
這種多次交換訊息的過程是網路通訊時常常碰到的情況!有個專有名詞叫做『交握』Hand Shaking。

至此同學可以開始測試程式傳影像檔了!首先可以用本機的兩個 Port 測試,如上一單元,開兩個程式實體,分別用不同的Port測試,成功後也可以跨機與其他同學互傳影像。

不過請注意!這是UDP不是FTP程式,一次的Send動作只能傳一個封包,太大的檔案是會超載的!乘載量經過測試大約50kB以下可以正常傳遞,大於50kB就會當掉!所以小圖案沒問題,一般照片就不太行了!
下載下面這些小動畫來測試都OK啦!

互傳影像之後的畫面可能如下(記得要寫對Port並啟動接收哦!):

為了隱私,部分IP被塗掉了!
>