天天看點

網絡開發:在Socket中發送大檔案

在使用Socket進行網絡程式設計的時候,一般都需要考慮一個包大小的問題。目前我們用得最大的情況是,每個包的大小為4KB(4096),但是,如果我們發送的資料要超過這個限制(這很常見),那麼應該怎麼辦呢?

Socket本身并不提供對于這種情況的實作,一般我們需要自己拆包群組裝。我下面寫了一個例子

下面是發送一個檔案的示範

服務端:

TcpListener server = null;

  private void btListen_Click(object sender, EventArgs e)

  {

      ThreadStart info = new ThreadStart(StartListener);

      Thread t = new Thread(info);

      t.Start();  

  }

  void StartListener()

      server = new TcpListener(IPAddress.Any,8090);

      try

      {

          server.Start();

          while (true)

          {

              TcpClient client = server.AcceptTcpClient();

              //直接給用戶端發送一個圖檔

              byte[] request = new byte[256];

              int i;

              if ((i=client.Client.Receive(request)) != 0)

              {

                  string path = Encoding.UTF8.GetString(request,0,i).Trim();

                  //發送大檔案

                  //1. 第一步:發送一個包,表示檔案的長度,讓用戶端知道後續要接收幾個包來重新組織成一個檔案

                  FileStream fs = new FileStream(path, FileMode.Open);

                  long length = fs.Length;

                  client.Client.Send(Encoding.UTF8.GetBytes(length.ToString()));

                  //2. 第二步:每次發送一個4KB的包,如果檔案較大,則會拆分為多個包

                  byte[] fileblock=new byte[4096];

                  while (fs.Read(fileblock,0,4096)!=0)

                  {

                      client.Client.Send(fileblock);

                  }

                  fs.Close();

              }

          }

      }

      catch (Exception ex)

          MessageBox.Show(ex.Message);

  }

用戶端

private void btTransfom_Click(object sender, EventArgs e)

{

     TcpClient client = new TcpClient();

     client.Connect("localhost", 8090);

     string request = @"e:\temp\test.jpg";

     client.Client.Send(Encoding.UTF8.GetBytes(request));

     byte[] result = new byte[4096];

     client.Client.Receive(result);//收取第一個包,裡面包含了檔案的長度資訊

     int length = int.Parse(Encoding.UTF8.GetString(result));

     byte[] file = new byte[4096];

     int total = length;

     MemoryStream ms = new MemoryStream();

     while (total > 0)

     {

         int count = client.Client.Receive(file);

         ms.Write(file, 0, count);

         ms.Flush();

         total -= count;

     }

     ms.Position = 0;

     Bitmap bitmap = new Bitmap(ms);

     pictureBox1.Image = bitmap;

}

繼續閱讀