欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#學習教程之Socket的簡單使用

 更新時間:2019年02月13日 08:23:04   作者:張子浩  
這篇文章主要給大家介紹了關于C#學習教程之Socket的簡單使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

在開始介紹socket前先補充補充基礎知識,在此基礎上理解網絡通信才會順理成章,當然有基礎的可以跳過去了。都是廢話,進入正題。

TCP/IP:Transmission Control Protocol/Internet Protocol,傳輸控制協議/因特網互聯協議,又名網絡通訊協議。簡單來說:TCP控制傳輸數據,負責發(fā)現傳輸的問題,一旦有問題就發(fā)出信號,要求重新傳輸,直到所有數據安全正確地傳輸到目的地,而IP是負責給因特網中的每一臺電腦定義一個地址,以便傳輸。從協議分層模型方面來講:TCP/IP由:網絡接口層(鏈路層)、網絡層、傳輸層、應用層。它和OSI的七層結構以及對于協議族不同,下圖簡單表示:

注:第一張圖:TCP/IP的四層結構對應OSI七層結構。

第三張圖:TCP/IP協議族在OSI七層中的位置及對應的功能。

第二張圖:TCP/IP協議模塊關系圖。

現階段socket通信使用TCP、UDP協議,相對應UDP來說,TCP則是比較安全穩(wěn)定的協議了。

Socket是一種通信TCP/IP的通訊接口,也就是HTTP的抽象層,就是Socket在Http之上,Socket也就是發(fā)動機。實際上,傳輸層的TCP是基于網絡層的IP協議的,而應用層的HTTP協議又是基于傳輸層的TCP協議的,而Socket本身不算是協議,就像上面所說,它只是提供了一個針對TCP或者UDP編程的接口。

在C#中可以非常方便的使用Socket進行數據傳輸。

Socket對象是C#使用它的重要對象在Socket的構造函數中,我們可以設置它的地址,Socket的類,支持的協議等等,其定義如下:

public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

我們想要使用Socket,那么就必須創(chuàng)建Socket的對象,創(chuàng)建這個對象,就必須需要IPEndPoint對象來綁定到套接詞字中,有如下定義

// 創(chuàng)建負責監(jiān)聽的套接字,注意其中的參數; 
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 獲得文本框中的IP對象;
IPAddress address = IPAddress.Parse(textBox1.Text.Trim());
// 創(chuàng)建包含ip和端口號的網絡節(jié)點對象; 
IPEndPoint endPoint = new IPEndPoint(address, int.Parse(textBox2.Text.Trim()));

然后再通過Socket的Bind來進行綁定。

socketWatch.Bind(endPoint);

因為我們時刻會被內網中的其他ip和端口進行連接,那么我們就需要創(chuàng)建線程來進行觀察,有如下定義

// 設置監(jiān)聽隊列的長度; 
   socketWatch.Listen(10);
   // 創(chuàng)建負責監(jiān)聽的線程; 
   threadWatch = new Thread(WatchConnecting);
   threadWatch.IsBackground = true;
   threadWatch.Start();
   ShowMsg("服務器啟動監(jiān)聽成功!");

其檢測方法如下,其中就是不斷的去檢測客戶端的連接請求,通過Accept()方法可以獲取一個套接字,然后通過Socket對象的RemoteEndPoint()可以獲取一個IP。

void WatchConnecting()
  {
   while (true) // 持續(xù)不斷的監(jiān)聽客戶端的連接請求; 
   {
    // 開始監(jiān)聽客戶端連接請求,Accept方法會阻斷當前的線程; 
    Socket sokConnection = socketWatch.Accept(); // 一旦監(jiān)聽到一個客戶端的請求,就返回一個與該客戶端通信的 套接字; 
    // 想列表控件中添加客戶端的IP信息; 
    Online.Items.Add(sokConnection.RemoteEndPoint.ToString());
    // 將與客戶端連接的 套接字 對象添加到集合中; 
    dict.Add(sokConnection.RemoteEndPoint.ToString(), sokConnection);
    ShowMsg("客戶端連接成功!");
    Thread thr = new Thread(RecMsg);
    thr.IsBackground = true;
    thr.Start(sokConnection);
    dictThread.Add(sokConnection.RemoteEndPoint.ToString(), thr); // 將新建的線程 添加 到線程的集合中去。 
   }
  }

最后我們開啟一個線程去執(zhí)行RecMsg方法,然后我們不停的去監(jiān)聽客戶端給我們的數據發(fā)送。

void RecMsg(object sokConnectionparn)
  {
   Socket sokClient = sokConnectionparn as Socket;
   while (true)
   {
    // 定義一個2M的緩存區(qū); 
    byte[] arrMsgRec = new byte[1024 * 1024 * 2];
    // 將接受到的數據存入到輸入 arrMsgRec中; 
    int length = -1;
    try
    {
     length = sokClient.Receive(arrMsgRec); // 接收數據,并返回數據的長度; 
    }
    catch (SocketException se)
    {
     ShowMsg("異常:" + se.Message);
     // 從 通信套接字 集合中刪除被中斷連接的通信套接字; 
     dict.Remove(sokClient.RemoteEndPoint.ToString());
     // 從通信線程集合中刪除被中斷連接的通信線程對象; 
     dictThread.Remove(sokClient.RemoteEndPoint.ToString());
     // 從列表中移除被中斷的連接IP 
     Online.Items.Remove(sokClient.RemoteEndPoint.ToString());
     break;
    }
    catch (Exception e)
    {
     ShowMsg("異常:" + e.Message);
     // 從 通信套接字 集合中刪除被中斷連接的通信套接字; 
     dict.Remove(sokClient.RemoteEndPoint.ToString());
     // 從通信線程集合中刪除被中斷連接的通信線程對象; 
     dictThread.Remove(sokClient.RemoteEndPoint.ToString());
     // 從列表中移除被中斷的連接IP 
     Online.Items.Remove(sokClient.RemoteEndPoint.ToString());
     break;
    }
    if (arrMsgRec[0] == 0) // 表示接收到的是數據; 
    {
     string strMsg = System.Text.Encoding.UTF8.GetString(arrMsgRec, 1, length - 1);// 將接受到的字節(jié)數據轉化成字符串; 
     ShowMsg(strMsg);
    }
    if (arrMsgRec[0] == 1) // 表示接收到的是文件; 
    {
     SaveFileDialog sfd = new SaveFileDialog();

     if (sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK)
     {// 在上邊的 sfd.ShowDialog() 的括號里邊一定要加上 this 否則就不會彈出 另存為 的對話框,而彈出的是本類的其他窗口,,這個一定要注意!?。 窘忉專杭恿藅his的sfd.ShowDialog(this),“另存為”窗口的指針才能被SaveFileDialog的對象調用,若不加thisSaveFileDialog 的對象調用的是本類的其他窗口了,當然不彈出“另存為”窗口?!?

      string fileSavePath = sfd.FileName;// 獲得文件保存的路徑; 
      // 創(chuàng)建文件流,然后根據路徑創(chuàng)建文件; 
      using (FileStream fs = new FileStream(fileSavePath, FileMode.Create))
      {
       fs.Write(arrMsgRec, 1, length - 1);
       ShowMsg("文件保存成功:" + fileSavePath);
      }
     }
    }
   }
  }

我們在方法中獲得了一個Object類型的對象,將這個Object對象轉換成了Socket,然后我們通過Socket的方法Receive()方法接收返回的數據,其中里面有它的屬性,可以獲取ip還有一些數據等等。服務器向客戶端發(fā)送數據也是非常簡單。通過Send方法就可以了,如以下定義:

string strMsg = "服務器" + "\r\n" + " -->" + richTextBox1.Text.Trim() + "\r\n";
   byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); // 將要發(fā)送的字符串轉換成Utf-8字節(jié)數組; 
   byte[] arrSendMsg = new byte[arrMsg.Length + 1];
   arrSendMsg[0] = 0; // 表示發(fā)送的是消息數據 
   Buffer.BlockCopy(arrMsg, 0, arrSendMsg, 1, arrMsg.Length);
   string strKey = "";
   strKey = Online.Text.Trim();
   if (string.IsNullOrEmpty(strKey)) // 判斷是不是選擇了發(fā)送的對象; 
   {
    MessageBox.Show("請選擇你要發(fā)送的好友?。?!");
   }
   else
   {
    dict[strKey].Send(arrSendMsg);// 解決了 sokConnection是局部變量,不能再本函數中引用的問題; 
    ShowMsg(strMsg);
    richTextBox1.Clear();
   }

最后需要注意的是,如果你的文件較大,有的時候這個緩沖區(qū)達不到你的文件字節(jié)那么大,那么就會截斷,所以與的時候,先將文件轉換為Byte是正確的做法。只要在客戶端進行逆轉就可以了!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • 微信小程序支付C#后端源碼

    微信小程序支付C#后端源碼

    這篇文章主要為大家詳細介紹了微信小程序支付C#后端源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • 利用Aspose.Cells和Excel模板導出統(tǒng)計數據

    利用Aspose.Cells和Excel模板導出統(tǒng)計數據

    這篇文章主要為大家詳細介紹了利用Aspose.Cells和Excel模板導出復雜的統(tǒng)計數據,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C#調用QQ_Mail發(fā)送郵件實例代碼兩例

    C#調用QQ_Mail發(fā)送郵件實例代碼兩例

    這篇文章介紹了C#調用QQ_Mail發(fā)送郵件的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C# Winform按鈕中圖片實現左圖右字的效果實例

    C# Winform按鈕中圖片實現左圖右字的效果實例

    這篇文章主要給大家介紹了關于C# Winform按鈕中圖片實現左圖右字效果的相關資料,文中通過圖文介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • C#中執(zhí)行批處理文件(*.bat)的方法代碼

    C#中執(zhí)行批處理文件(*.bat)的方法代碼

    本文介紹一下在C#中執(zhí)行批處理文件(*.bat)的方法。
    2013-03-03
  • C#?使用?Filestream?修改大文件指定位置數據

    C#?使用?Filestream?修改大文件指定位置數據

    這篇文章主要介紹了C#?使用?Filestream修改大文件指定位置數據,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • C#實現利用泛型將DataSet轉為Model的方法

    C#實現利用泛型將DataSet轉為Model的方法

    這篇文章主要介紹了C#實現利用泛型將DataSet轉為Model的方法,實例分析了C#泛型的相關使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • C#實現AI五子棋游戲的示例代碼

    C#實現AI五子棋游戲的示例代碼

    這篇文章主要為大家詳細介紹了C#如何智能AI五子棋游戲中的人工下棋操作以及對應的機器操作,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-11-11
  • C#中抽象方法與虛擬方法的區(qū)別

    C#中抽象方法與虛擬方法的區(qū)別

    這篇文章主要介紹了C#中抽象方法與虛擬方法的區(qū)別,對于C#初學者來說可以深入理解抽象方法與虛擬方法,需要的朋友可以參考下
    2014-08-08
  • C#使用StreamReader和StreamWriter類讀寫操作文件

    C#使用StreamReader和StreamWriter類讀寫操作文件

    這篇文章介紹了C#使用StreamReader和StreamWriter類讀寫操作文件的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05

最新評論