步驟:
一、服務端的建立
1.服務端的項目建立以及頁面佈局
2.各功能按鍵的事件代碼
1)傳輸類型說明以及全局變量
2)Socket通信服務端具體步驟:
(1)建立一個Socket
(2)接收信息
(3)發送數據(這裏分發送字符串、文件(包含大文件)、震動)
二、客戶端的建立
1.服務端的項目建立以及頁面佈局
2.各功能按鍵的事件代碼
1)傳輸類型說明以及全局變量
2)Socket通信服務端具體步驟:
(1)建立一個Socket
(2)接收信息
(3)發送數據(這裏分發送字符串、文件(包含大文件)、震動)
注意:此圖是Socket通信的精華,在使用Socket通信時,有什麼迷惑的可以看看此圖,下面我們講解的時候也是參照此圖
Socket大家肯定很熟悉,對已內部的通信邏輯,肯定也有一定得了解---
對於Socket研究了兩天寫了一個小程序,通過Socket服務端與客戶端的通信,以及大文件之間斷點的傳輸(這裏只做了服務端給客戶端傳送大文件,如果想把客戶端的大文件傳送給服務端也是一樣的道理,看了文章,大家肯定可以自己實現)······
(自己才疏學淺,如有bug請諒解,但功能還是能實現的)
下面根據步驟進入正題:
一、服務端的建立
1.服務端的項目建立以及頁面佈局
新建解決方案“Socket通信”以及兩個Winform項目(1)SockeClient——客戶端 (2)SocketServer——服務器
給服務端界面佈局——參照上圖(這個大家肯定都是手到擒來就不累贅了······)
2.各功能按鍵的事件代碼
先把整個服務端的代碼貼出來,然後我們在一一講解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
|
1)傳輸類型說明以及全局變量
這些說明以及全局變量,說的也比較清楚,也不累贅了。
2)Socket通信服務端具體步驟:
(這些步驟都是根據第一個圖來的)
(1)建立一個Socket
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
|
在開啓監聽按鈕裏,我們建立了Socket,以及監聽的最大客戶端數 socketWatch.Listen(10)
由於服務端會不停的去監視接收客戶端發來的信息,如果把這個工作放到主線程裏,程序會出現假死的現象,所以這裏給他放到一個新的線程裏。
(2)接收信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
接收信息是會根據接收到字節數字的第一個字節來判斷接收到的是什麼
這個在方法Recive裏進行判斷
1 |
|
namespace SocketClient { public partial class Form1 : Form { //說明:在傳遞信息的時候,會在需要傳遞的信息前面加一個字符來標識傳遞的是不同的信息 // 0:表示傳遞的是字符串信息 // 1:表示傳遞的是文件信息 // 2:表示的是震動 /// <summary> /// 用來存放連接服務的IP地址和端口號,對應的Socket (這個爲了以後的擴展用,現在暫時沒用) /// </summary> Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>(); /// <summary> /// 存儲保存文件的路徑 /// </summary> string filePath = ""; /// <summary> /// 負責通信的Socket /// </summary> Socket socketSend; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //不檢測跨線程之間的空間調用 Control.CheckForIllegalCrossThreadCalls = false; } /// <summary> /// 建立連接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { try { //創建負責通信的Socket socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //獲取服務端的IP IPAddress ip = IPAddress.Parse(txtServer.Text.Trim()); //獲取服務端的端口號 IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text)); //獲得要連接的遠程服務器應用程序的IP地址和端口號 socketSend.Connect(port); ShowMsg("連接成功"); //新建線程,去接收客戶端發來的信息 Thread td = new Thread(AcceptMgs); td.IsBackground = true; td.Start(); } catch { } } /// <summary> /// 接收數據 /// </summary> private void AcceptMgs() { try { /// <summary> /// 存儲大文件的大小 /// </summary> long length = 0; long recive = 0; //接收的大文件總的字節數 while (true) { byte[] buffer = new byte[1024 * 1024]; int r = socketSend.Receive(buffer); if (r == 0) { break; } if (length > 0) //判斷大文件是否已經保存完 { //保存接收的文件 using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write)) { fsWrite.Write(buffer, 0, r); length -= r; //減去每次保存的字節數 ShowMsg(string.Format("{0}: 已接收:{1}/{2}", socketSend.RemoteEndPoint, recive-length, recive)); if (length <= 0) { ShowMsg(socketSend.RemoteEndPoint + ": 接收文件成功"); } continue; } } if (buffer[0] == 0) //如果接收的字節數組的第一個字節是0,說明接收的字符串信息 { string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1); ShowMsg(socketSend.RemoteEndPoint.ToString() + ": " + strMsg); } else if (buffer[0] == 1) //如果接收的字節數組的第一個字節是1,說明接收的是文件 { length = int.Parse(Encoding.UTF8.GetString(buffer,1,r-1)); recive = length; filePath = ""; SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "保存文件"; sfd.InitialDirectory = @"C:\Users\Administrator\Desktop"; sfd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; //如果沒有選擇保存文件路徑就一直打開保存框 while (true) { sfd.ShowDialog(this); filePath = sfd.FileName; if (string.IsNullOrEmpty(filePath)) { continue; } else { break; } } } else if (buffer[0] == 2) //如果接收的字節數組的第一個字節是2,說明接收的是震動 { ZD(); } } } catch { } } /// <summary> /// 顯示信息 /// </summary> /// <param name="message"></param> private void ShowMsg(string message) { txtLog.AppendText(message + "\r\n"); } /// <summary> /// 發送數據 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSend_Click(object sender, EventArgs e) { try { byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); //獲得發送的信息時候,在數組前面加上一個字節 0 List<byte> list = new List<byte>(); list.Add(0); list.AddRange(buffer); //將泛型集合轉換爲數組 byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer); txtMsg.Text = ""; } catch{} } /// <summary> /// 選擇文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSelect_Click(object sender, EventArgs e) { //打開文件 OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "選擇要傳的文件"; ofd.InitialDirectory = @"C:\Users\Administrator\Desktop"; ofd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; ofd.ShowDialog(); //得到選擇文件的路徑 txtPath.Text = ofd.FileName; } /// <summary> /// 發送文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSendFile_Click(object sender, EventArgs e) { try { string filePath = txtPath.Text; if (string.IsNullOrEmpty(filePath)) { MessageBox.Show("請選擇文件"); return; } //讀取選擇的文件 using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read)) { byte[] buffer = new byte[1024 * 1024 * 2]; int r = fsRead.Read(buffer, 0, buffer.Length); //獲得發送的信息時候,在數組前面加上一個字節 1 List<byte> list = new List<byte>(); list.Add(1); list.AddRange(buffer); byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer, 0, r + 1, SocketFlags.None); txtPath.Text = ""; } } catch{ } } /// <summary> /// 震動 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnZD_Click(object sender, EventArgs e) { try { // 首字節是2說明是震動 byte[] buffer = new byte[1]; buffer[0] = 2; socketSend.Send(buffer); } catch{ } } /// <summary> /// 震動 /// </summary> private void ZD() { //獲取當前窗體的座標 Point point = this.Location; //反覆給窗體座標複製一百次,達到震動的效果 for (int i = 0; i < 100; i++) { this.Location = new Point(point.X - 5, point.Y - 5); this.Location = new Point(point.X + 5, point.Y + 5); } this.Location = point; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
|
(3)發送數據(這裏分發送字符串、文件(包含大文件)、震動)
發送字符串信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
|
發送震動
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|
發送文件(包含大文件)
首先要選擇文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
然後在發送文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
|
注意:(1)發送文件的時候會分兩步發送 :第一步:發送一個包,表示文件的長度,讓客戶端知道後續要接收幾個包來重新組織成一個文件
第二步:每次發送一個1MB的包,如果文件較大,則會拆分爲多個包
(2)每個客戶端連接服務端的啥時候,都會把客戶端的ip以及端口號,放到下拉框裏,想給那個客戶端發信息,就選擇對應的客戶端
二、客戶端的建立
1.客戶端的項目建立以及頁面佈局
客戶端的界面佈局與服務端很像,就是把對應的開始監聽換成連接,當然代碼也會有所改變,後面會講到·····
2.各功能按鍵的事件代碼
先把整個服客戶端的代碼貼出來,然後我們在一一講解
namespace SocketClient { public partial class Form1 : Form { //說明:在傳遞信息的時候,會在需要傳遞的信息前面加一個字符來標識傳遞的是不同的信息 // 0:表示傳遞的是字符串信息 // 1:表示傳遞的是文件信息 // 2:表示的是震動 /// <summary> /// 用來存放連接服務的IP地址和端口號,對應的Socket (這個爲了以後的擴展用,現在暫時沒用) /// </summary> Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>(); /// <summary> /// 存儲保存文件的路徑 /// </summary> string filePath = ""; /// <summary> /// 負責通信的Socket /// </summary> Socket socketSend; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { //不檢測跨線程之間的空間調用 Control.CheckForIllegalCrossThreadCalls = false; } /// <summary> /// 建立連接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { try { //創建負責通信的Socket socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //獲取服務端的IP IPAddress ip = IPAddress.Parse(txtServer.Text.Trim()); //獲取服務端的端口號 IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text)); //獲得要連接的遠程服務器應用程序的IP地址和端口號 socketSend.Connect(port); ShowMsg("連接成功"); //新建線程,去接收客戶端發來的信息 Thread td = new Thread(AcceptMgs); td.IsBackground = true; td.Start(); } catch { } } /// <summary> /// 接收數據 /// </summary> private void AcceptMgs() { try { /// <summary> /// 存儲大文件的大小 /// </summary> long length = 0; long recive = 0; //接收的大文件總的字節數 while (true) { byte[] buffer = new byte[1024 * 1024]; int r = socketSend.Receive(buffer); if (r == 0) { break; } if (length > 0) //判斷大文件是否已經保存完 { //保存接收的文件 using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write)) { fsWrite.Write(buffer, 0, r); length -= r; //減去每次保存的字節數 ShowMsg(string.Format("{0}: 已接收:{1}/{2}", socketSend.RemoteEndPoint, recive-length, recive)); if (length <= 0) { ShowMsg(socketSend.RemoteEndPoint + ": 接收文件成功"); } continue; } } if (buffer[0] == 0) //如果接收的字節數組的第一個字節是0,說明接收的字符串信息 { string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1); ShowMsg(socketSend.RemoteEndPoint.ToString() + ": " + strMsg); } else if (buffer[0] == 1) //如果接收的字節數組的第一個字節是1,說明接收的是文件 { length = int.Parse(Encoding.UTF8.GetString(buffer,1,r-1)); recive = length; filePath = ""; SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "保存文件"; sfd.InitialDirectory = @"C:\Users\Administrator\Desktop"; sfd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; //如果沒有選擇保存文件路徑就一直打開保存框 while (true) { sfd.ShowDialog(this); filePath = sfd.FileName; if (string.IsNullOrEmpty(filePath)) { continue; } else { break; } } } else if (buffer[0] == 2) //如果接收的字節數組的第一個字節是2,說明接收的是震動 { ZD(); } } } catch { } } /// <summary> /// 顯示信息 /// </summary> /// <param name="message"></param> private void ShowMsg(string message) { txtLog.AppendText(message + "\r\n"); } /// <summary> /// 發送數據 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSend_Click(object sender, EventArgs e) { try { byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); //獲得發送的信息時候,在數組前面加上一個字節 0 List<byte> list = new List<byte>(); list.Add(0); list.AddRange(buffer); //將泛型集合轉換爲數組 byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer); txtMsg.Text = ""; } catch{} } /// <summary> /// 選擇文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSelect_Click(object sender, EventArgs e) { //打開文件 OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "選擇要傳的文件"; ofd.InitialDirectory = @"C:\Users\Administrator\Desktop"; ofd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; ofd.ShowDialog(); //得到選擇文件的路徑 txtPath.Text = ofd.FileName; } /// <summary> /// 發送文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSendFile_Click(object sender, EventArgs e) { try { string filePath = txtPath.Text; if (string.IsNullOrEmpty(filePath)) { MessageBox.Show("請選擇文件"); return; } //讀取選擇的文件 using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read)) { byte[] buffer = new byte[1024 * 1024 * 2]; int r = fsRead.Read(buffer, 0, buffer.Length); //獲得發送的信息時候,在數組前面加上一個字節 1 List<byte> list = new List<byte>(); list.Add(1); list.AddRange(buffer); byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer, 0, r + 1, SocketFlags.None); txtPath.Text = ""; } } catch{ } } /// <summary> /// 震動 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnZD_Click(object sender, EventArgs e) { try { // 首字節是2說明是震動 byte[] buffer = new byte[1]; buffer[0] = 2; socketSend.Send(buffer); } catch{ } } /// <summary> /// 震動 /// </summary> private void ZD() { //獲取當前窗體的座標 Point point = this.Location; //反覆給窗體座標複製一百次,達到震動的效果 for (int i = 0; i < 100; i++) { this.Location = new Point(point.X - 5, point.Y - 5); this.Location = new Point(point.X + 5, point.Y + 5); } this.Location = point; } } }
1)傳輸類型說明以及全局變量
這些說明以及全局變量,說的也比較清楚,也不累贅了。
2)Socket通信服務端具體步驟:
(這些步驟都是根據第一個圖來的)
(1)建立一個通信的Socket
/// <summary> /// 建立連接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnStart_Click(object sender, EventArgs e) { try { //創建負責通信的Socket socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //獲取服務端的IP IPAddress ip = IPAddress.Parse(txtServer.Text.Trim()); //獲取服務端的端口號 IPEndPoint port = new IPEndPoint(ip, Convert.ToInt32(txtPort.Text)); //獲得要連接的遠程服務器應用程序的IP地址和端口號 socketSend.Connect(port); ShowMsg("連接成功"); //新建線程,去接收客戶端發來的信息 Thread td = new Thread(AcceptMgs); td.IsBackground = true; td.Start(); } catch { } }
在連接按鈕裏,我們建立了Socket
由於客戶端會不停的去監視接收服務端發來的信息,如果把這個工作放到主線程裏,程序會出現假死的現象,所以這裏給他放到一個新的線程裏。
(2)接收信息
/// <summary> /// 接收數據 /// </summary> private void AcceptMgs() { try { /// <summary> /// 存儲大文件的大小 /// </summary> long length = 0; long recive = 0; //接收的大文件總的字節數 while (true) { byte[] buffer = new byte[1024 * 1024]; int r = socketSend.Receive(buffer); if (r == 0) { break; } if (length > 0) //判斷大文件是否已經保存完 { //保存接收的文件 using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write)) { fsWrite.Write(buffer, 0, r); length -= r; //減去每次保存的字節數 ShowMsg(string.Format("{0}: 已接收:{1}/{2}", socketSend.RemoteEndPoint, recive-length, recive)); if (length <= 0) { ShowMsg(socketSend.RemoteEndPoint + ": 接收文件成功"); } continue; } } if (buffer[0] == 0) //如果接收的字節數組的第一個字節是0,說明接收的字符串信息 { string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1); ShowMsg(socketSend.RemoteEndPoint.ToString() + ": " + strMsg); } else if (buffer[0] == 1) //如果接收的字節數組的第一個字節是1,說明接收的是文件 { length = int.Parse(Encoding.UTF8.GetString(buffer,1,r-1)); recive = length; filePath = ""; SaveFileDialog sfd = new SaveFileDialog(); sfd.Title = "保存文件"; sfd.InitialDirectory = @"C:\Users\Administrator\Desktop"; sfd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; //如果沒有選擇保存文件路徑就一直打開保存框 while (true) { sfd.ShowDialog(this); filePath = sfd.FileName; if (string.IsNullOrEmpty(filePath)) { continue; } else { break; } } } else if (buffer[0] == 2) //如果接收的字節數組的第一個字節是2,說明接收的是震動 { ZD(); } } } catch { } }
接收信息是會根據接收到字節數字的第一個字節來判斷接收到的是什麼,如果接收的是個大文件,首先會接收大文件的大小,然後根據大小接收相同大小的字節數組追加保存到一個文件裏去。
(3)發送數據(這裏分發送字符串、文件(包含大文件)、震動)
發送字符串信息
/// <summary> /// 發送數據 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSend_Click(object sender, EventArgs e) { try { byte[] buffer = Encoding.UTF8.GetBytes(txtMsg.Text); //獲得發送的信息時候,在數組前面加上一個字節 0 List<byte> list = new List<byte>(); list.Add(0); list.AddRange(buffer); //將泛型集合轉換爲數組 byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer); txtMsg.Text = ""; } catch{} }
發送震動
/// <summary> /// 震動 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnZD_Click(object sender, EventArgs e) { try { // 首字節是2說明是震動 byte[] buffer = new byte[1]; buffer[0] = 2; socketSend.Send(buffer); } catch{ } } /// <summary> /// 震動 /// </summary> private void ZD() { //獲取當前窗體的座標 Point point = this.Location; //反覆給窗體座標複製一百次,達到震動的效果 for (int i = 0; i < 100; i++) { this.Location = new Point(point.X - 5, point.Y - 5); this.Location = new Point(point.X + 5, point.Y + 5); } this.Location = point; }
發送文件(不包含大文件)
首先要選擇文件
/// <summary> /// 選擇文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSelect_Click(object sender, EventArgs e) { //打開文件 OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "選擇要傳的文件"; ofd.InitialDirectory = @"C:\Users\Administrator\Desktop"; ofd.Filter = "文本文件|*.txt|圖片文件|*.jpg|視頻文件|*.avi|所有文件|*.*"; ofd.ShowDialog(); //得到選擇文件的路徑 txtPath.Text = ofd.FileName; }
然後在發送文件
/// <summary> /// 發送文件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnSendFile_Click(object sender, EventArgs e) { try { string filePath = txtPath.Text; if (string.IsNullOrEmpty(filePath)) { MessageBox.Show("請選擇文件"); return; } //讀取選擇的文件 using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read)) { byte[] buffer = new byte[1024 * 1024 * 2]; int r = fsRead.Read(buffer, 0, buffer.Length); //獲得發送的信息時候,在數組前面加上一個字節 1 List<byte> list = new List<byte>(); list.Add(1); list.AddRange(buffer); byte[] newBuffer = list.ToArray(); //將了標識字符的字節數組傳遞給客戶端 socketSend.Send(newBuffer, 0, r + 1, SocketFlags.None); txtPath.Text = ""; } } catch{ } }