C#.網路程式設計 Socket基礎(三) 基於WinForm系統Socket TCP協議 實現端到端(伺服器與客戶端).txt.word.png等不同型別檔案傳輸
阿新 • • 發佈:2018-12-17
一、簡介:
前面的兩篇介紹了字串傳輸、圖片傳輸:
其實,本文針對Socket基礎(二)進一步完成,以便可以進行多種檔案傳輸。
二、基於不同的流(檔案流、記憶體流、網路等)讀寫。
1、圖片傳輸
方法一:(在客戶端用檔案流傳送(即將圖片寫到檔案流去,以便傳送),在服務端用記憶體流來接收(即從記憶體流讀取圖片出來))
方法二:(在客戶端用檔案流傳送(即將圖片寫到檔案流去,以便傳送),在服務端也用檔案流來接收(即從檔案流讀取圖片出來))
服務端程式碼:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketServer_SendImage { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //Form1_Load表示預設的載入,相當於初始化。 private void Form1_Load(object sender, EventArgs e) { lab_pro.Text = "接收:0/100"; //button1.Text = "BBBBB"; } /// <summary> /// 開啟服務 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { button1.Text = "監聽中..."; button1.Enabled = false; Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888); //設定接收資料緩衝區的大小 byte[] b = new byte[4096]; receiveSocket.Bind(hostIpEndPoint); //監聽 receiveSocket.Listen(2); //接受客戶端連線 Socket hostSocket = receiveSocket.Accept(); //記憶體流fs的初始容量大小為0,隨著資料增長而擴充套件。 //MemoryStream fs = new MemoryStream(); string Path = "C:\\Users\\lanmage2\\Desktop\\AA"; FileStream fs = new FileStream(Path + "\\新圖片.png", FileMode.Create, FileAccess.Write); int length = 0; //每接受一次,只能讀取小於等於緩衝區的大小4096個位元組 while ((length = hostSocket.Receive(b)) > 0) { //將接受到的資料b,按長度length放到記憶體流中。 fs.Write(b, 0, length); if (progressBar1.Value < 100) { //進度條的預設值為0 progressBar1.Value++; lab_pro.Text = "接收:" + progressBar1.Value + "/100"; } } progressBar1.Value = 100; lab_pro.Text = "接收:" + progressBar1.Value + "/100"; fs.Flush(); /*Bitmap類,可以將*/ //Bitmap Img = new Bitmap(fs); //Img.Save(@"reveive.jpg", ImageFormat.Png); //關閉寫檔案流 fs.Close(); //關閉接收資料的Socket hostSocket.Shutdown(SocketShutdown.Receive); hostSocket.Close(); //關閉傳送連線 receiveSocket.Close(); } } }
2、傳輸文件(比如.txt文件或其他)
方法一:
服務端大部分程式碼參考 1、圖片傳輸 方法二 的程式碼,但是其改動了截圖部分
方法2:
在客戶端用檔案流傳送(即將圖片寫到檔案流去,以便傳送),在服務端用記憶體流來快取,並用檔案流來輸出,這種方法是最理想的,既可以傳圖片,可以傳其他任意檔案:
伺服器端:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace SocketServer_SendImage { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //Form1_Load表示預設的載入,相當於初始化。 private void Form1_Load(object sender, EventArgs e) { lab_pro.Text = "接收:0/100"; //button1.Text = "BBBBB"; } /// <summary> /// 開啟服務 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { button1.Text = "監聽中..."; button1.Enabled = false; Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888); //設定接收資料緩衝區的大小 byte[] b = new byte[4096]; receiveSocket.Bind(hostIpEndPoint); //監聽 receiveSocket.Listen(2); //接受客戶端連線 Socket hostSocket = receiveSocket.Accept(); //記憶體流fs的初始容量大小為0,隨著資料增長而擴充套件。 MemoryStream fs = new MemoryStream(); //string Path = "C:\\Users\\lanmage2\\Desktop\\AA"; //FileStream fs = new FileStream(Path, FileMode.Open); int length = 0; //每接受一次,只能讀取小於等於緩衝區的大小4096個位元組 while ((length = hostSocket.Receive(b)) > 0) { //將接受到的資料b,按長度length放到記憶體流中。 fs.Write(b, 0, length); if (progressBar1.Value < 100) { //進度條的預設值為0 progressBar1.Value++; lab_pro.Text = "接收:" + progressBar1.Value + "/100"; } } progressBar1.Value = 100; lab_pro.Text = "接收:" + progressBar1.Value + "/100"; fs.Flush(); fs.Seek(0, SeekOrigin.Begin); byte[] byteArray = new byte[fs.Length]; int count = 0; while (count < fs.Length) { byteArray[count] = Convert.ToByte(fs.ReadByte()); count++; } string Path = "C:\\Users\\lanmage2\\Desktop\\AA"; //FileStream filestream = new FileStream(Path + "\\檔案1.txt", FileMode.OpenOrCreate); FileStream filestream = File.Create(Path); //filestream.Write(byteArray, 0, byteArray.Length);//不能用 //System.IO.File.WriteAllBytes(Path, byteArray);//能用 /*Bitmap類,可以將*/ //Bitmap Img = new Bitmap(fs); //Img.Save(@"reveive.jpg", ImageFormat.Png); //關閉寫檔案流 fs.Close(); //關閉接收資料的Socket hostSocket.Shutdown(SocketShutdown.Receive); hostSocket.Close(); //關閉傳送連線 receiveSocket.Close(); } } }
三、總結
本文隨意可以傳輸不同型別的檔案,但是沒辦法動態識別不同的檔案型別,不夠靈活。在我下一篇文章,將根據使用者端傳送的資訊,將對不同的檔案型別進行動態的識別。