基於UDP的檔案傳輸軟體 C

2021-07-30 02:09:38 字數 2425 閱讀 9784

完成乙個區域網內的基於udp的檔案傳輸系統,該軟體有客戶端與服務端,服務端繫結ip、埠,監聽接收檔案的訊息,客戶端連線服務端,向其傳送選中檔案,傳送檔案過程中允許兩端終端檔案傳輸。同時需要支援多個客戶端的檔案傳送。

附兩張老師需求文件中介面的截圖:

在專案要求和中把很多點都列舉出來了,這裡列個表

基於udp,服務端還繫結ip埠,當時我一想,鑽了個牛角尖:使用同乙個埠怎麼可能支援多個客戶端?期間還想起了學習計算機網路的知識,udp的socket只通過本機的ip和埠標識乙個連線,這樣的話,豈不是所有客戶端的連線,只要接入同乙個服務端的ip和埠,就只能被識別為乙個連線了?資料怎麼傳,做不成吧。

問了老師,老師只回答了用多執行緒,並沒有解決udp使用同乙個ip埠的問題。

後來做起來,漸漸想清楚了,繫結乙個ip和埠肯定是不行的,這其實是讓我們手動模擬tcp的socket.accept函式,每次接到乙個連線請求,就重新分配乙個埠號用於傳輸。

從上面的需求介面可以看到,街面上需要顯示當前傳輸檔案的進度,進度是實時更新的。這其實是乙個難點。因為傳輸肯定是要放到ui執行緒之外來做的,否則ui會卡死,但是ui控制項的更新卻只能由ui執行緒來做,這是矛盾的。自然,這種矛盾不僅我們遇到過,無數用c#寫桌面程式的人都遇到過,查一下,就有了答案,通過使用synchronizationcontext,將希望ui執行緒更新的資訊,藉由同步上下文使用訊息佇列傳送給ui執行緒,交由ui執行緒來做。

還是基於2中的問題,實時更新,其實是乙個細粒度的事情,這表示底層socket傳送的過程中要向上層反饋訊息,訊息再由訊息佇列交付給ui執行緒,那麼底層向上層傳送訊息怎麼實現呢?自己寫訊息佇列然後上層輪詢,可以,但這個訊息佇列就要手寫了。方法應該有很多種,我想到了c#的語法——委託。可以讓上層實現訊息交付給ui執行緒的函式,而底層持有這個函式的委託(相當於函式指標),這樣底層既可以呼叫直接呼叫上層的函式了。

這個時候就突然想起了從哪兒看到的,c#常用於開發桌面應用,所以才有了委託這個語法。確實,委託就像拋向底層的鉤子,ui的事情只能上層來做,通過這些鉤子卻可以讓底層也能做。
這兩部分其實是邊寫程式邊修改的,程式寫好了,設計也配套做好。原因是我想早早實踐,這樣的流程不符合軟體開發的傳統模型,比如瀑布流等,但是似乎符合敏捷開發,當然這是給自己貼金,不寫文件不等於敏捷開發。

時序圖

我組長總結的系統設計圖:

上圖是我組長畫的系統設計圖,整個程式可以分出server和client兩個頭,兩個頭介面和內部邏輯有些不同,相同的地方向下沉,沉到下一層的control裡,control裡有資訊控制、檔案傳送、檔案接收等主要3個類,分為3個模組。

下面是各個類的介紹:

內部封裝乙個udp的sokcet,用於傳送、接收訊息

訊息按型別分為系統、檔案資訊、檔案控制、埠訊息、使用者訊息,傳送時將訊息型別和內容拼接成字串傳送,接收後拆分。

函式介紹:

用於傳送乙個檔案,內部封裝了乙個socket

函式介紹:

用於乙個接收檔案

函式介紹:

用於管理檔案傳送

函式介紹:

用於管理檔案接收

函式介紹:

用於規定一些公共變數,以及工具方法

函式介紹:

至此呢,應該說需求分析和設計就算是完成了,編碼工作也同步完成,下面說下不足,也就是編碼沒考慮周全的地方

輸入資料的檢測:如果服務端填寫的不是本機ip會怎樣?肯定不行是吧,但是我沒有做這方面的檢測

多執行緒管理:現在的程式,是開了執行緒就不管了,等著執行緒裡的任務跑完或者超時殺死執行緒。其實在util類裡我是放過乙個鍊錶來收集執行緒的,並且有退出殺死鍊錶中所有執行緒的函式,但細粒度的管理並不知道怎麼做

功能劃分,或者模組劃分:其實寫起來還是有些東西不知道劃分在哪兒,比如msgctrl,是客戶端服務端使用同乙個類,還是特化出兩個不同類,**結構還要改進;此外,msgctrl應該單拿出來的,我將其方法寫在了介面**裡,增加了耦合。

隨機埠:隨機埠部分,可以用,但是沒有檢測埠被搶占了的問題,應該將使用中的埠放入乙個set,每次隨機的埠需要先判斷是否已使用

好,上面的內容一看完,這個程式除了能跑通就沒優點了。

其實這個程式已經重構過一次了,先前那一版,因為腦袋裡沒有全域性的設計,導致有幾個部分功能劃分重疊,現在**結構更清爽點。

UDP通訊及檔案傳輸

udp通訊 理解幾個名詞 1.datagramsocket 用來傳送和接收資料報的套接字 socket 資料報套接字是包投遞服務的傳送或接收點。每個在資料報套接字上傳送或接收的包都是單獨編址和路由的。從一台機器傳送到另一台機器的多個包可能選擇不同的路由,也可能按不同的順序到達。2.datagramp...

基於TCP的檔案傳輸

伺服器端處理客戶請求 public class serverthread extends thread override public void run file file new file directory.getabsolutepath file.separatorchar filename ...

linux下udp大檔案傳輸

近日小弟做了個linux下使用者資料報協議大檔案傳輸程式發上來與大家共勉。在 redhat 9.0 下編譯通過。最大測試無差錯傳輸檔案 288m 最大測試傳輸速度 6.5m s 可能這裡並不需要這種型別的帖子,但希望各位能代小弟轉貼,因為網路上很難搜尋到這種可以解決丟包問題的 級實現方法,希望每乙個...