Socket傳輸大文件(發送與接收)


下載

Client

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Windows.Forms;


namespace SocketClient
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            SocketClient();
        }
        public static string serverIp = "127.0.0.1";//設置服務端IP
        public static int serverPort = 8888;//服務端端口
        public static Socket socketClient;//定義socket
        public static Thread threadClient;//定義線程
        public static byte[] result = new byte[1024];//定義緩存
        public static void SocketClient()
        {
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//創建一個socket的對象
            IPAddress ip = IPAddress.Parse(serverIp);//獲取服務器IP地址
            IPEndPoint point = new IPEndPoint(ip, serverPort);//獲取端口
            try
            {
                socketClient.Connect(point);//鏈接服務器IP與端口
                Console.WriteLine("連接服務器中.....");

            }
            catch (Exception)
            {
                Console.WriteLine("與服務器鏈接失敗!!!");
                return;
            }
            Console.WriteLine("與服務器鏈接成功!!!");
            try
            {
                Thread.Sleep(1000);    //等待1秒鍾  
                //通過 socketClient 向服務器發送數據
                string sendMessage = "已成功接到SocketClient發送的消息";//發送到服務端的內容
                byte[] send = Encoding.UTF8.GetBytes(sendMessage);//Encoding.UTF8.GetBytes()將要發送的字符串轉換成UTF8字節數組
                byte[] SendMsg = new byte[send.Length + 1];//定義新的字節數組
                SendMsg[0] = 0;//將數組第一位設置為0,來表示發送的是消息數據  
                Buffer.BlockCopy(send, 0, SendMsg, 1, send.Length);//偏移復制字節數組
                socketClient.Send(SendMsg);  //將接受成功的消息返回給SocketServer服務器 
                Console.WriteLine("發送完畢:{0}", sendMessage);

            }                                                                                                                     
            catch
            {
                socketClient.Shutdown(SocketShutdown.Both);//禁止Socket上的發送和接受
                socketClient.Close();//關閉Socket並釋放資源
            }
            //打開文件
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Title = "選擇要傳的文件";
            ofd.InitialDirectory = @"E:\IVS\Down";
            //ofd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*";
            ofd.ShowDialog();
            //得到選擇文件的路徑
            string filePath = ofd.FileName;//獲取文件的完整路徑
            Console.WriteLine("發送的文件路徑為:"+filePath);
            using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read))
            {
                //1. 第一步:發送一個文件,表示文件名和長度,讓客戶端知道后續要接收幾個包來重新組織成一個文件
                string fileName = Path.GetFileName(filePath);
                Console.WriteLine("發送的文件名是:" + fileName);
                long fileLength = fsRead.Length;//文件長度
                Console.WriteLine("發送的文件長度為:"+fileLength);
                string totalMsg = string.Format("{0}-{1}", fileName, fileLength);
                byte[] buffer = Encoding.UTF8.GetBytes(totalMsg); 
                byte[] newBuffer = new byte[buffer.Length + 1];
                newBuffer[0] = 2;
                Buffer.BlockCopy(buffer, 0, newBuffer, 1, buffer.Length);
                socketClient.Send(newBuffer);//發送文件前,將文件名和長度發過去
                //2第二步:每次發送一個1MB的包,如果文件較大,則會拆分為多個包
                byte[] Filebuffer = new byte[1024 * 1024 * 5];//定義1MB的緩存空間
                int readLength = 0;  //定義讀取的長度
                bool firstRead = true;
                long sentFileLength = 0;//定義發送的長度
                while ((readLength = fsRead.Read(buffer, 0, buffer.Length)) > 0 && sentFileLength < fileLength)
                {
                    sentFileLength += readLength;
                    //第一次發送的字節流上加個前綴1
                    if (firstRead)
                    {
                        byte[] firstBuffer = new byte[readLength + 1];
                        firstBuffer[0] = 1;//標記1,代表為文件
                        Buffer.BlockCopy(buffer, 0, firstBuffer, 1, readLength);
                        socketClient.Send(firstBuffer, 0, readLength + 1, SocketFlags.None);
                        Console.WriteLine("第一次讀取數據成功,在前面添加一個標記");
                        firstRead = false;
                        continue;
                    }
                    socketClient.Send(buffer, 0, readLength, SocketFlags.None);
                    Console.WriteLine("{0}: 已發送數據:{1}/{2}", socketClient.RemoteEndPoint, sentFileLength, fileLength);
                }
                fsRead.Close();
                Console.WriteLine("發送完成");
            }
            Console.ReadLine();
        }
    }

}

Server

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using System.Windows.Forms;

namespace SocketServer
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            SocketServer();
        }
        public static string serverIp = "127.0.0.1";//設置服務端IP
        public static int serverPort = 8888;//服務端端口
        public static Socket socketServer;//定義socket
        public static Thread threadWatch;//定義線程
        public static byte[] result = new byte[1024 * 1024 * 2];//定義緩存
        //public static string fileName;//獲取文件名
        public static string filePath = "";//存儲保存文件的路徑
        public static void SocketServer()
        {
            socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//創建一個socket的對象
            IPAddress ip = IPAddress.Parse(serverIp);//獲取服務器IP地址
            IPEndPoint point = new IPEndPoint(ip, serverPort);//獲取端口
            try
            {
                socketServer.Bind(point);//綁定IP地址及端口
            }
            catch (Exception ex)
            {
                Console.WriteLine("綁定IP時出現異常:" + ex.Message);
                return;
            }
            socketServer.Listen(100);//開啟監聽並設定最多10個排隊連接請求
            threadWatch = new Thread(WatchConnect);//創建一個監聽進程
            threadWatch.IsBackground = true;//后台啟動
            threadWatch.Start();//運行
            Console.WriteLine("服務器{0}監聽啟動成功!", socketServer.LocalEndPoint.ToString());
            Console.ReadLine();
        }
        public static void WatchConnect()
        {
            while (true)
            {
                Socket watchConnect = socketServer.Accept();//接收連接並返回一個新的Socket
                watchConnect.Send(Encoding.UTF8.GetBytes("服務器連接成功"));//在客戶端顯示"服務器連接成功"提示
                Thread threadwhat = new Thread(ReceiveMsg);//創建一個接受信息的進程
                threadwhat.IsBackground = true;//后台啟動
                threadwhat.Start(watchConnect);//有傳入參數的線程
            }
        }
        public static DateTime GetTime()
        {
            DateTime now = new DateTime();
            now = DateTime.Now;
            return now;
        }
        public static void ReceiveMsg(object watchConnect)
        {
            Socket socketServer = watchConnect as Socket;
            long fileLength = 0;//文件長度
            string recStr = null;//文件名
            while (true)
            {
                int firstRcv = 0;
                byte[] buffer = new byte[1024 * 1024 * 5];
                try
                {
                    //獲取接受數據的長度,存入內存緩沖區,返回一個字節數組的長度
                    if (socketServer != null) firstRcv = socketServer.Receive(buffer);
                    if (firstRcv > 0)//大於0,說明有東西傳過來
                    {
                        if (buffer[0] == 0)//0對應文字信息
                        {
                            string recMsg = Encoding.UTF8.GetString(buffer, 1, firstRcv - 1);
                            Console.WriteLine("客戶端接收到信息:" + socketServer.LocalEndPoint.ToString() + "\r\n" + GetTime() + "\r\n" + recMsg + "\r\n");
                        }

                        if (buffer[0] == 1)//1對應文件信息
                        {
                            SaveFileDialog sfDialog = new SaveFileDialog();//創建SaveFileDialog實例
                            string spath = @"E:\存放";//制定存儲路徑
                            string savePath = Path.Combine(spath, recStr);//獲取存儲路徑及文件名
                            int rec = 0;
                            long recFileLength = 0;
                            bool firstWrite = true;
                            using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                            {
                                while (recFileLength < fileLength)
                                {
                                    if (firstWrite)
                                    {
                                        fs.Write(buffer, 1, firstRcv - 1);
                                        fs.Flush();
                                        recFileLength += firstRcv - 1;
                                        firstWrite = false;
                                    }
                                    else
                                    {
                                        rec = socketServer.Receive(buffer);
                                        fs.Write(buffer, 0, rec);
                                        fs.Flush();
                                        recFileLength += rec;
                                    }
                                    Console.WriteLine("{0}: 已接收數據:{1}/{2}", socketServer.RemoteEndPoint, recFileLength, fileLength);
                                }
                                fs.Close();
                            }
                            Console.WriteLine("保存成功!!!!");
                        }
                        if (buffer[0] == 2)//2對應文件名字和長度
                        {
                            string fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstRcv - 1);
                            recStr = fileNameWithLength.Split('-').First();//獲取文件名
                            Console.WriteLine("接收到的文件名為:" + recStr);
                            fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());//獲取文件長度
                            Console.WriteLine("接收到的文件長度為:" + fileLength);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("系統異常..." + ex.Message);
                    break;
                }
            }

            //while (true)
            //{
            //    int num = -1;//初始化num
            //    string reveiceName;//定義字符串
            //    try
            //    {
            //        num = socketClient.Receive(result);//獲取客戶端信息
            //        reveiceName = Encoding.UTF8.GetString(result, 0, num);//把從0到num的字節變成String
            //    }
            //    catch (SocketException ex)
            //    {
            //        Console.WriteLine("異常:" + ex.Message + ", RemoteEndPoint: " + socketClient.RemoteEndPoint.ToString());
            //        break;
            //    }
            //    catch (Exception ex)
            //    {
            //        Console.WriteLine("異常:" + ex.Message);
            //        break;
            //    }

            //while (true)
            //{

            //try
            //{
            //    /// <summary>
            //    /// 存儲大文件的大小
            //    /// </summary>
            //   long length = 0;
            //   long recive = 0; //接收的大文件總的字節數
            //    while (true)
            //    {
            //        byte[] buffer = new byte[1024 * 1024];
            //        int r = socketClient.Receive(buffer);
            //        Console.WriteLine("接受到的字符長度" + r);
            //        if (r == 0)
            //        {
            //            break;
            //        }
            //        Console.WriteLine("第二次的length長度為:" + length);
            //        if (length > 0)  //判斷大文件是否已經保存完
            //        {
            //            //保存接收的文件
            //            using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write))
            //            {
            //                Console.WriteLine("-----------------11111111111111111111111-----------------------------");
            //                fsWrite.Write(buffer, 0, r);
            //                length -= r; //減去每次保存的字節數
            //                Console.WriteLine("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive);
            //                if (length <= 0)
            //                {
            //                    Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
            //                }
            //                continue;
            //            }
            //        }
            //        if (buffer[0] == 0) //如果接收的字節數組的第一個字節是0,說明接收的字符串信息
            //        {
            //            string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1);
            //            Console.WriteLine("*****************0000000000000000000000*********************");
            //            Console.WriteLine(socketClient.RemoteEndPoint.ToString() + ": " + strMsg);
            //        }
            //        else if (buffer[0] == 1) //如果接收的字節數組的第一個字節是1,說明接收的是文件
            //        {
            //            Console.WriteLine("++++++++++++++111111111111111111111+++++++++++++++++++");
            //            length = int.Parse(Encoding.UTF8.GetString(buffer, 1, r - 1));
            //            recive = length;
            //            Console.WriteLine("接收到的字節長度是多少呢:?" + length);
            //            SaveFileDialog sfd = new SaveFileDialog();
            //            sfd.Title = "保存文件";
            //            sfd.InitialDirectory = @"C:\Users\Administrator\Desktop";
            //            //sfd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*";
            //            //如果沒有選擇保存文件路徑就一直打開保存框
            //            SaveFileDialog save = new SaveFileDialog();//創建SaveFileDialog實例
            //            string spath = @"C:\Users\admin\Desktop";//制定存儲路徑
            //            filePath = Path.Combine(spath, fileName);//獲取存儲路徑及文件名
            //        }
            //    }
            //}
            //catch { }

            //}
















            //try
            //{
            //    if (reveiceName[0] == 0)//判斷數組第一個值,如果為0則說明傳的是信息
            //    {
            //        fileName = Encoding.UTF8.GetString(result, 1, num - 1);//提取字節信息並轉換成String
            //        Console.WriteLine("接收客戶端的消息:{0}", fileName);
            //    }
            //    if (reveiceName[0] == 1)//判斷數組第一個值,如果為1則說明傳的是文件
            //    {
            //        SaveFileDialog save = new SaveFileDialog();//創建SaveFileDialog實例
            //        string spath = @"C:\Users\admin\Desktop";//制定存儲路徑
            //        string fullPath = Path.Combine(spath, fileName);//獲取存儲路徑及文件名
            //        //FileStream filesave = new FileStream(fullPath, FileMode.Create, FileAccess.Write);//創建文件流,用來寫入數據
            //        //filesave.Write(result, 1, num - 1);//將數據寫入到文件中
            //        //filesave.Close();
            //        //Console.WriteLine("保存成功!!!");
            //        //**************************************************************************************************
            //        while (true)
            //        {
            //            byte[] buffer = new byte[1024 * 1024];
            //            int r = socketClient.Receive(buffer);
            //            Console.WriteLine("從客戶端接收到的字節數:"+r);
            //            //string leng = Encoding.UTF8.GetString(buffer, 1, r - 1);
            //            int recive = r - 1;
            //            //Console.WriteLine(leng);
            //            //long recive = int.Parse(leng);
            //            //long recive = Convert.ToInt64(Encoding.UTF8.GetString(buffer, 1, r - 1));
            //            Console.WriteLine("總接受字節數:" + recive);
            //            long length = recive;
            //            Console.WriteLine("*******************************************");
            //            if (length > 0)
            //            {
            //                using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
            //                {
            //                    Console.WriteLine("---------*************--------------");
            //                    fsWrite.Write(buffer,1, r-1);
            //                    length -= r; //減去每次保存的字節數
            //                    Console.WriteLine("剩余接受字節數:"+length);
            //                    Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive));
            //                    if (length <= 0)
            //                    {
            //                        Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
            //                    }
            //                }
            //            }
            //        }


            //        //long recive = 0; //接收的大文件總的字節數
            //        //while (true)
            //        //{
            //        //    //byte[] buffer = new byte[1024 * 1024];
            //        //    //int r = socketClient.Receive(buffer);

            //        //    if (num == 0)
            //        //    {
            //        //        break;
            //        //    }
            //        //    if (length > 0)  //判斷大文件是否已經保存完
            //        //    {
            //        //        //保存接收的文件
            //        //        using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
            //        //        {
            //        //            fsWrite.Write(result, 1, num-1);
            //        //            length -= num; //減去每次保存的字節數
            //        //            Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive-length, recive));
            //        //            if (length <= 0)
            //        //            {
            //        //               Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
            //        //            }
            //        //            continue;
            //        //        }                        
            //        //    }
            //    }
            //}
            //catch (Exception ex)
            //{

            //    Console.WriteLine(ex.Message);
            //}

            //}

        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM