程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#網絡編程(訂立協議和發送文件) - Part.4(1)

C#網絡編程(訂立協議和發送文件) - Part.4(1)

編輯:關於C語言

文件傳輸

前面兩篇文章所使用的范例都是傳輸字符串,有的時候我們可能會想在服務端和客戶端之間傳遞文件 。比如,考慮這樣一種情況,假如客戶端顯示了一個菜單,當我們輸入S1、S2或S3(S為Send縮寫)時, 分別向服務端發送文件Client01.jpg、Client02.jpg、ClIEnt03.jpg;當我們輸入R1、R2或R3時(R為 Receive縮寫),則分別從服務端接收文件Server01.jpg、Server02.jpg、Server03.jpg。那麼,我們該 如何完成這件事呢?此時可能有這樣兩種做法:

類似於FTP協議,服務端開辟兩個端口,並持續對這兩個端口偵聽:一個用於接收字符串,類似於FTP 的控制端口,它接收各種命令(接收或發送文件);一個用於傳輸數據,也就是發送和接收文件。

服務端只開辟一個端口,用於接收字符串,我們稱之為控制端口。當接到請求之後,根據請求內容在 客戶端開辟一個端口專用於文件傳輸,並在傳輸結束後關閉端口。

現在我們只關注於上面的數據端口,回憶一下在第二篇中我們所總結的,可以得出:當我們使用上面 的方法一時,服務端的數據端口可以為多個客戶端的多次請求服務;當我們使用方法二時,服務端只為一 個客戶端的一次請求服務,但是因為每次請求都會重新開辟端口,所以實際上還是相當於可以為多個客戶 端的多次請求服務。同時,因為它只為一次請求服務,所以我們在數據端口上傳輸文件時無需采用異步傳 輸方式。但在控制端口我們仍然需要使用異步方式。

從上面看出,第一種方式要好得多,但是我們將采用第二種方式。至於原因,你可以回顧一下Part.1 (基本概念和操作)中關於聊天程序模式的講述,因為接下來一篇文章我們將創建一個聊天程序,而這個 聊天程序采用第三種模式,所以本文的練習實際是對下一篇的一個鋪墊。

1.訂立協議

1.1發送文件

我們先看一下發送文件的情況,如果我們想將文件clIEnt01.jpg由客戶端發往客戶端,那麼流程是什 麼:

客戶端開辟數據端口用於偵聽,並獲取端口號,假設為8005。

假設客戶端輸入了S1,則發送下面的控制字符串到服務端:[file=ClIEnt01.jpg, mode=send, port=8005]。

服務端收到以後,根據客戶端ip和端口號與該客戶端建立連接。

客戶端偵聽到服務端的連接,開始發送文件。

傳送完畢後客戶端、服務端分別關閉連接。

此時,我們訂立的發送文件協議為:[file=ClIEnt01.jpg, mode=send, port=8005]。但是,由於它是 一個普通的字符串,在上一篇中,我們采用了正則表達式來獲取其中的有效值,但這顯然不是一種好辦法 。因此,在本文及下一篇文章中,我們采用一種新的方式來編寫協議:XML。對於上面的語句,我們可以 寫成這樣的XML:

<protocol><file name="clIEnt01.jpg" mode="send" port="8005" /></protocol>

這樣我們在服務端就會好處理得多,接下來我們來看一下接收文件的流程及其協議。

NOTE:這裡說發送、接收文件是站在客戶端的立場說的,當客戶端發送文件時,對於服務器來收,則 是接收文件。

1.2接收文件

接收文件與發送文件實際上完全類似,區別只是由客戶端向網絡流寫入數據,還是由服務端向網絡流 寫入數據。

客戶端開辟數據端口用於偵聽,假設為8006。

假設客戶端輸入了R1,則發送控制字符串:<protocol><file name="Server01.jpg" mode="receive" port="8006" /></protocol>到服務端。

服務端收到以後,根據客戶端ip和端口號與該客戶端建立連接。

客戶端建立起與服務端的連接,服務端開始網絡流中寫入數據。

傳送完畢後服務端、客戶端分別關閉連接。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved