程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#網絡編程(同步傳輸字符串) - Part.2(3)

C#網絡編程(同步傳輸字符串) - Part.2(3)

編輯:關於C語言

現在再次運行程序,得到的輸出為:

// 服務端
Server is running ...
Start Listening ...
ClIEnt Connected!127.0.0.1:8500 <-- 127.0.0.1:7847
Reading data, 52 bytes ...
Received: "Welcome To TraceFact.Net"
輸入"Q"鍵退出。
// 客戶端
ClIEnt Running ...
Server Connected!127.0.0.1:7847 --> 127.0.0.1:8500
Sent: "Welcome To TraceFact.Net"
輸入"Q"鍵退出。

再繼續進行之前,我們假設客戶端可以發送多條消息,而服務端要不斷的接收來自客戶端發送的消息 ,但是上面的代碼只能接收客戶端發來的一條消息,因為它已經輸出了“輸入Q鍵退出”,說明程序已經 執行完畢,無法再進行任何動作。此時如果我們再開啟一個客戶端,那麼出現的情況是:客戶端可以與服 務器建立連接,也就是netstat-a顯示為ESTABLISHED,這是操作系統所知道的;但是由於服務端的程序已 經執行到了最後一步,只能輸入Q鍵退出,無法再采取任何的動作。

回想一個上面我們需要一個服務器對應多個客戶端時,對AcceptTcpClIEnt()方法的處理辦法,將它放 在了do/while循環中;類似地,當我們需要一個服務端對同一個客戶端的多次請求服務時,可以將Read() 方法放入到do/while循環中。

現在,我們大致可以得出這樣幾個結論:

如果不使用do/while循環,服務端只有一個listener.AcceptTcpClient()方法和一個 TcpClIEnt.GetStream().Read()方法,則服務端只能處理到同一客戶端的一條請求。

如果使用一個do/while循環,並將listener.AcceptTcpClient()方法和TcpClIEnt.GetStream().Read ()方法都放在這個循環以內,那麼服務端將可以處理多個客戶端的一條請求。

如果使用一個do/while循環,並將listener.AcceptTcpClient()方法放在循環之外,將 TcpClIEnt.GetStream().Read()方法放在循環以內,那麼服務端可以處理一個客戶端的多條請求。

如果使用兩個do/while循環,對它們進行分別嵌套,那麼結果是什麼呢?結果並不是可以處理多個客 戶端的多條請求。因為裡層的do/while循環總是在為一個客戶端服務,因為它會中斷在 TcpClient.GetStream().Read()方法的位置,而無法執行完畢。即使可以通過某種方式讓裡層循環退出, 比如客戶端往服務端發去“exit”字符串時,服務端也只能挨個對客戶端提供服務。如果服務端想執行多 個客戶端的多個請求,那麼服務端就需要采用多線程。主線程,也就是執行外層do/while循環的線程,在 收到一個TcpClient之後,必須將裡層的do/while循環交給新線程去執行,然後主線程快速地重新回到 listener.AcceptTcpClIEnt()的位置,以響應其它的客戶端。

對於第四種情況,實際上是構建一個服務端更為通常的情況,所以需要專門開辟一個章節討論,這裡 暫且放過。而我們上面所做的,即是列出的第一種情況,接下來我們再分別看一下第二種和第三種情況。

對於第二種情況,我們按照上面的敘述先對服務端進行一下改動:

do {
    // 獲取一個連接,中斷方法
    TcpClient remoteClient = listener.AcceptTcpClIEnt();
    // 打印連接到的客戶端信息
    Console.WriteLine("ClIEnt Connected!{0} <-- {1}",
        remoteClient.Client.LocalEndPoint, remoteClient.ClIEnt.RemoteEndPoint);

    // 獲得流,並寫入buffer中
    NetworkStream streamToClient = remoteClIEnt.GetStream();
    byte[] buffer = new byte[BufferSize];
    int bytesRead = streamToClIEnt.Read(buffer, 0, BufferSize);
    Console.WriteLine("Reading data, {0} bytes ...", bytesRead);

    // 獲得請求的字符串
    string msg = Encoding.Unicode.GetString(buffer, 0, bytesRead);
    Console.WriteLine("Received: {0}", msg);
} while (true);

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