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); //} //} } } }
