日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

c#实现Socket网络编程

發布時間:2024/4/17 C# 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c#实现Socket网络编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

命名空間:

  在網絡環境下,我們最感興趣的兩個命名空間是System.Net和?System.Net.Sockets

  System.Net命名空間通常與較高程的操作有關,例如downloadupload,試用HTTP和其他協議進行Web請求等等

  System.Net.Sockets命名空間所包含的類通常與較低程的操作有關。如果要直接使用Sockets或者?TCP/IP之類的協議

?

Socket對象創建:

  針對Socket編程,.NET?框架的?Socket?類是?Winsock32?API?提供的套接字服務的托管代碼版本。Socket可以象流Stream一樣被視為一個數據通道,這個通道架設在應用程序端(客戶端)和遠程服務器端之間,而后,數據的讀取(接收)和寫入(發送)均針對這個通道來進行。

  Socket?類支持兩種基本模式:同步和異步。其區別在于:在同步模式中,對執行網絡操作的函數(如?Send?和?Receive)的調用一直等到操作完成后才將控制返回給調用程序。在異步模式中,這些調用立即返回。?

?

  在使用之前,你需要首先創建Socket對象的實例,這可以通過Socket類的構造方法來實現:?

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

  其中,addressFamily?參數指定?Socket?使用的尋址方案,socketType?參數指定?Socket?的類型,protocolType?參數指定?Socket?使用的協議。?

  下面的示例語句創建一個?Socket,它可用于在基于?TCP/IP?的網絡(如?Internet)上通訊。?

Socket?temp?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Stream,?ProtocolType.Tcp);?

  若要使用?UDP?而不是?TCP,需要更改協議類型,如下面的示例所示:?

Socket?temp?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Dgram,?ProtocolType.Udp);?

一旦創建?Socket,在客戶端,你將可以通過Connect方法連接到指定的服務器,并通過Send/SendTo

?

Socket操作流程:

  方法向遠程服務器發送數據,而后可以通過?Receive/ReceiveFrom從服務端接收數據;而在服務器端,你需要使用Bind方法綁定所指定的接口使Socket與一個本地終結點相聯,并通過Listen方法偵聽該接口上的請求,當偵聽到用戶端的連接時,調用Accept完成連接的操作,創建新的Socket以處理傳入的連接請求。使用完?Socket?后,記住使用?Shutdown?方法禁用?Socket,并使用?Close?方法關閉?Socket。

?

終結點:

  在Internet中,TCP/IP?使用套接字(一個網絡地址和一個服務端口號)來唯一標識設備。網絡地址(IP)標識網絡上的特定設備;端口號(Port)標識要連接到的該設備上的特定服務。網絡地址和服務端口的組合稱為終結點,在?.NET?框架中正是由?EndPoint?類表示這個終結點,它提供表示網絡資源或服務的抽象,用以標志網絡地址等信息。

  .Net同時也為每個受支持的地址族定義了?EndPoint?的子代;對于?IP?地址族,該類為?IPEndPoint。IPEndPoint?類包含應用程序連接到主機上的服務所需的主機和端口信息

?

IP地址獲取方式:

  用到IPEndPoint類的時候就不可避免地涉及到計算機IP地址,System.Net命名空間中有兩種類可以得到IP地址實例:?

  IPAddress:?在同一局域網中采用的獲取方式。?IPAddress?類包含計算機在?IP?網絡上的地址。其Parse方法可將?IP?地址字符串轉換為?IPAddress?實例。下面的語句創建一個?IPAddress?實例:?

IPAddress?myIP?=?IPAddress.Parse("192.168.0.1");?

  Dns?:??在互聯網中采用的獲取方式。?向使用?TCP/IP?Internet?服務的應用程序提供域名服務。其Resolve?方法查詢?DNS?服務器以將用戶友好的域名(如"host.mydomain.com")映射到數字形式的?Internet?地址(如?192.168.0.1)。

  Resolve方法?返回一個?IPHostEnty?實例,該實例包含所請求名稱的地址和別名的列表。大多數情況下,可以使用?AddressList?數組中返回的第一個地址。下面的代碼獲取一個?IPAddress?實例,該實例包含服務器?host.mydomain.com?的?IP?地址。?

  IPHostEntry?ipHostInfo?=?Dns.Resolve("host.mydomain.com?");?

  IPAddress?ipAddress?=?ipHostInfo.AddressList[0];?

  你也可以使用GetHostName方法得到IPHostEntry實例:?

  IPHosntEntry?hostInfo=Dns.GetHostByName("host.mydomain.com?")?

  在使用以上方法時,你將可能需要處理以下幾種異常:?

  SocketException異常:訪問Socket時操作系統發生錯誤引發?

  ArgumentNullException異常:參數為空引用引發?

  ObjectDisposedException異常:Socket已經關閉引發

?

通信過程示例:

?

服務器端:

?

服務器端接收客戶端數據步驟:

?

  • 創建一個服務器端的實體
  • 創建服務器端對客戶端的監聽
  • EndAccept方法返回客戶端實體
  • 新建線程負責接收客戶端的數據
  • ?

    ?

    public class CM{public static bool ISAddSocekt = true;//現在是否繼續接收新的客戶端連接public static int AddressIndex = 0;//這是當前與服務器端連接的第幾個客戶端 //病歷號和客戶端IP關聯表(key:病歷號 value:客戶端的IP地址,不包含port)public static Dictionary<string, string> dic_Patient_IP = new Dictionary<string, string>();//客戶端IP和客戶端連接順序關聯表(key:病歷號 value:客戶端的IP地址,不包含port)public static Dictionary<string, int> dic_IP_Index = new Dictionary<string, int>();//客戶端集合 key:客戶端IP地址,Value:客戶端實體public static Dictionary<string, Socket> dic_IP_Socket = new Dictionary<string, Socket>();private delegate void AcceptDelegete();private delegate void ReadDelegete(Socket s);public static int ServerPort = 2000;//服務器端端口public static Socket serverSocket;//服務器端 //用20個線程分別接受一個設備的數據public static int ClientCount_Max = 20;//客戶端的最大數量public static void Listen(){AcceptDelegete listen = AcceptConnection;IAsyncResult asy = listen.BeginInvoke(null, null);}private static void AcceptConnection(){try{serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint localEP = new IPEndPoint(IPAddress.Any, ServerPort);//將socket綁定到本地的終結點上 serverSocket.Bind(localEP);//開始監聽 serverSocket.Listen(ClientCount_Max);serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);}catch (Exception ex){}}private static void AcceptCallBack(IAsyncResult iar){try{while (ISAddSocekt){// 調用EndAccept完成BeginAccept異步調用,返回一個新的Socket處理與客戶的通信Socket clientSocket = serverSocket.EndAccept(iar);IPEndPoint clientPoint = clientSocket.RemoteEndPoint as IPEndPoint;if (!dic_IP_Index.ContainsKey(clientPoint.Address.ToString())){dic_IP_Index.Add(clientPoint.Address.ToString(), AddressIndex);AddressIndex += 1;//去除舊的客戶端實體 dic_IP_Socket.Remove(clientPoint.Address.ToString());}dic_IP_Socket.Add(clientPoint.Address.ToString(), clientSocket);//開啟新線程讀取數據CM_Data client = new CM_Data(clientSocket);Thread thClient = new Thread(new ThreadStart(client.ClientServer));thClient.Start();//在達到多大的客戶端連接限制前,繼續監聽是否有新的客戶端連接if (dic_IP_Index.Count < ClientCount_Max){serverSocket.BeginAccept(new AsyncCallback(AcceptCallBack), null);}}}catch (Exception ex){}}}//在新線程中不同的循環接收客戶端發送過來的數據信息// CM_Data類里的代碼public class CM_Data{Encoding encoding = Encoding.GetEncoding("GB2312"); //解碼器(可以用于漢字)private Socket client;//當前與服務器端通信的客戶端實體private byte[] receiveBytes = new byte[1024];//服務器端設置緩沖區private int recCount;byte[] byte_Data;//傳遞連接socketpublic CM_Data(Socket ClientSocket){this.client = ClientSocket;}public void ClientServer(){try{while (true){recCount = client.Receive(receiveBytes, receiveBytes.Length, 0);//從客戶端接收信息,recCount為有效數據的個數if (recCount != 0)//當服務器端的緩沖區接收到的信息不為空時 {byte_Data = new byte[recCount];for (int i = 0; i < recCount; i++){byte_Data[i] = receiveBytes[i];}//獲取數據后的數據處理 DataRead(byte_Data);}else{break;}}}catch (Exception ex){MessageBox.Show("數據接收時發生錯誤:"+ex.Message);}client.Close();} 服務器端接收客戶端數據

    ?

    ?

    服務器端向客戶端發送數據:

  • 獲取當前與服務器端通信的客戶端(或者要與之通信的目標客戶端)
  • BeginSend?將數據發送,要發送的數據使用的是byte數組的形式。
  • 示例中向客戶端發送的數據也是異步發送的
  • public void WorkCommand(string clientIP,int WorkState){Socket client = (Socket)CM.dic_IP_Socket[clientIP];byte[] b1 = new byte[6];b1[0] = 0x55;b1[1] = 0xaa;b1[2] = 0x04;b1[3] = 0x81;switch (WorkState){case 1: b1[4] = 0x01; break;case 2: b1[4] = 0x02; break;case 3: b1[4] = 0x03; break;case 4: b1[4] = 0x04; break;}b1[5] = CM_Data.GetParityBit(b1) ;client.BeginSend(b1, 0, b1.Length, SocketFlags.None, new AsyncCallback(SendCallBack), client);}private void SendCallBack(IAsyncResult iar){Socket workerSocket = (Socket)iar.AsyncState;workerSocket.EndSend(iar);} 服務器端向客戶端發送數據

    ?

    客戶端:

      項目的客戶端代碼是否下位機完成的(使用C++代碼),下面的客戶端示例,是我在測試程序中使用到的c#版本的代碼示例。

    客戶端接收服務器端數據步驟:

  • 創建客戶端實體,IPEndPoint?里指定的是服務器端的IP地址和服務器端的端口號。
  • 客戶端等待服務器端的連接。
  • 客戶端循環等待服務器端的發送數據
  • private int serverPort = 2000;public byte[] dataBuffer = new byte[10000000];Socket client;//連接服務器private void ServerConnection(){try{client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPAddress ip = IPAddress.Parse("192.168.10.188");IPEndPoint iep = new IPEndPoint(ip, 2000);client.BeginConnect(iep, new AsyncCallback(Connect), null);}catch { }}private void Connect(IAsyncResult asy){try{client.EndConnect(asy);client.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);}catch { }}//接收byte字節方式private void RecieveCallBack(IAsyncResult iar){try{int iRx = client.EndReceive(iar);byte[] byte_Receive = new byte[iRx];for (int i = 0; i < iRx; i++){byte_Receive[i] = dataBuffer[i];listBox1.Items.Add(Convert.ToString(byte_Receive[i], 16));}string revStr = System.Text.Encoding.UTF7.GetString(byte_Receive, 0, iRx);//繼續監聽下一次的數據接收client.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(RecieveCallBack), null);}catch { }} 客戶端接收服務器端數據 Void SendMessage() { try {byte[] buffer = System.Text.Encoding.Default.GetBytes(textBox1.Text);int snLen = 0;client.BeginSend(buffer, snLen, buffer.Length, SocketFlags.None, new AsyncCallback(SendCallBack), client);}catch { } } 客戶端向服務器端發送數據

    ?

    ?

    轉載于:https://www.cnblogs.com/eye-like/p/3993435.html

    總結

    以上是生活随笔為你收集整理的c#实现Socket网络编程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。