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

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

編輯:關於C語言

這裡應該沒有什麼新知識,需要注意的地方有這麼幾個:

在OnReadComplete()回調方法中的foreach循環,我們使用委托異步調用了handleProtocol()方法,這 是因為handleProtocol即將執行的是一個讀取或接收文件的操作,也就是一個相對耗時的操作。

在handleProtocol()方法中,我們深切體會了定義ProtocolHelper類和FileProtocol結構的好處。如 果沒有定義它們,這裡將是不堪入目的處理XML以及類型轉換的代碼。

handleProtocol()方法中進行了一個條件判斷,注意sendFile()方法我屏蔽掉了,這個還沒有實現, 但是我想你已經猜到它將是後面要實現的內容。

receiveFile()方法是實際接收客戶端發來文件的方法,這裡沒有什麼特別之處。需要注意的是文件存 儲的路徑,它保存在了當前程序執行的目錄下,文件的名稱我使用generateFileName()生成了一個與時間 有關的隨機名稱。

3.2客戶端的實現

我們現在先不著急實現客戶端S1、R1等用戶菜單,首先完成發送文件這一功能,實際上,就是為上一 節SendMessage()加一個姐妹方法SendFile()。

class ClIEnt {
    static void
Main(string[] args) {
        ConsoleKey key;

        ServerClient client = new ServerClIEnt();
        string filePath = Environment.CurrentDirectory + "/" + "ClIEnt01.jpg";

        if(File.Exists(filePath))
            clIEnt.BeginSendFile(filePath);

        Console.WriteLine("\n\n輸入\"Q\"鍵退出。");
        do {
            key = Console.ReadKey(true).Key;
        } while (key != ConsoleKey.Q);
    }
}

public class ServerClIEnt {
    private const int BufferSize = 8192;
    private byte[] buffer;
    private TcpClient clIEnt;
    private NetworkStream streamToServer;

    public ServerClIEnt() {
        try {
            client = new TcpClIEnt();
            clIEnt.Connect("localhost", 8500);      // 與服務器連接
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            return;
        }
        buffer = new byte[BufferSize];

        // 打印連接到的服務端信息
        Console.WriteLine("Server Connected!{0} --> {1}",
            client.Client.LocalEndPoint, client.ClIEnt.RemoteEndPoint);

        streamToServer = clIEnt.GetStream();
    }

    // 發送消息到服務端
    public void SendMessage(string msg) {

        byte[] temp = Encoding.Unicode.GetBytes(msg);   // 獲得緩存
        try {
            lock (streamToServer) {
                streamToServer.Write(temp, 0, temp.Length); // 發往服務器
            }
            Console.WriteLine("Sent: {0}", msg);
        } catch (Exception ex) {
            Console.WriteLine(ex.Message);
            return;
        }
    }

    // 發送文件 - 異步方法
    public void BeginSendFile(string filePath) {
        ParameterizedThreadStart start =
            new ParameterizedThreadStart(BeginSendFile);
        start.BeginInvoke(filePath, null, null);
    }

    private void BeginSendFile(object obj) {
        string filePath = obj as string;
        SendFile(filePath);
    }

    // 發送文件 -- 同步方法
    public void SendFile(string filePath) {

        IPAddress ip = IPAddress.Parse("127.0.0.1");
        TcpListener listener = new TcpListener(ip, 0);
        listener.Start();

        // 獲取本地偵聽的端口號
        IPEndPoint endPoint = listener.LocalEndpoint as IPEndPoint;
        int listeningPort = endPoint.Port;

        // 獲取發送的協議字符串
        string fileName = Path.GetFileName(filePath);
        FileProtocol protocol =
            new FileProtocol(FileRequestMode.Send, listeningPort, fileName);
        string pro = protocol.ToString();

        SendMessage(pro);       // 發送協議到服務端

        // 中斷,等待遠程連接
        TcpClient localClient = listener.AcceptTcpClIEnt();
        Console.WriteLine("Start sending file...");
        NetworkStream stream = localClIEnt.GetStream();

        // 創建文件流
        FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
        byte[] fileBuffer = new byte[1024];     // 每次傳1KB
        int bytesRead;
        int totalBytes = 0;

        // 創建獲取文件發送狀態的類
        SendStatus status = new SendStatus(filePath);

        // 將文件流轉寫入網絡流
        try {
            do {
                Thread.Sleep(10);           // 為了更好的視覺效果 ,暫停10毫秒:-)
                bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length);
                stream.Write(fileBuffer, 0, bytesRead);
                totalBytes += bytesRead;            // 發送了的 字節數
                status.PrintStatus(totalBytes); // 打印發送狀態
            } while (bytesRead > 0);
            Console.WriteLine("Total {0} bytes sent, Done!", totalBytes);
        } catch {
            Console.WriteLine("Server has lost...");
        }

        stream.Dispose();
        fs.Dispose();
        localClIEnt.Close();
        listener.Stop();
    }
}

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