程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C# Socket的TCP通訊的實例代碼

C# Socket的TCP通訊的實例代碼

編輯:C#入門知識

C# Socket的TCP通訊的實例代碼。本站提示廣大學習愛好者:(C# Socket的TCP通訊的實例代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是C# Socket的TCP通訊的實例代碼正文


Socket的TCP通訊

一、 socket的通訊原理

服務器端的步驟如下。

(1)樹立服務器端的Socket,開端偵聽整個網絡中的銜接懇求。

(2)當檢測到來自客戶端的銜接懇求時,向客戶端發送收到銜接懇求的信息,並樹立與客戶端之間的銜接。

(3)當完成通訊後,服務器封閉與客戶端的Socket銜接。

客戶端的步驟如下。

(1)樹立客戶端的Socket,確定要銜接的服務器的主機名和端口。

(2)發送銜接懇求到服務器,並等候服務器的回饋信息。

(3)銜接成功後,與服務器停止數據的交互。

(4)數據處置終了後,封閉本身的Socket銜接。

二、 socket的通訊方式

socket通訊方式有兩種:同步和異步

同步任務方式:

用TCP協議停止編程時順序執行到發送、接納和監聽語句的時分,在未完成任務前不再持續往下執行,即處於阻塞形態,直到該語句完成某個任務後才持續執行下一條語句。

異步任務方式

順序執行到發送、接納和監聽語句的時分,不管任務能否完成,都會持續往下執行。

三、 socket的C#完成

1.1. 同步:

服務端客戶端通訊

在與服務端的銜接樹立當前,我們就可以經過此銜接來發送和接納數據。端口與端口之間以流(Stream)的方式傳輸數據,由於簡直任何對象都可以保管到流中,所以實踐上可以在客戶端與服務端之間傳輸任何類型的數據。對客戶端來說,往流中寫入數據,即為向服務器傳送數據;從流中讀取數據,即為從服務端接納數據。對服務端來說,往流中寫入數據,即為向客戶端發送數據;從流中讀取數據,即為從客戶端接納數據。

服務端:

(1)服務端對端口停止偵聽:

服務器端樹立一個socket,設置好本機的ip和監聽的端口與socket停止綁定,開端監聽銜接懇求,當接納到銜接懇求後,發送確認,同客戶端樹立銜接,開端與客戶端停止通訊。

TcpListener listener =new TcpListener(new IPEndPoint(IPAddress.Parse(ip), port));//ip為服務器IP地址,port為監聽的端口

Listener.Start();//開啟監聽

(2)檢測來自客戶端的銜接懇求

TcpClient remoteClient = listener.AcceptTcpClient();
//接納客戶端 這裡表現了同步的含義,假如客戶端對該服務端發起銜接的時分,順序在這裡就會等候(阻塞),直到有客戶端的銜接懇求為止

(3)樹立和銜接的客戶端的數據流(傳輸數據)

NetworkStream streamToClient = remoteClient.GetStream();

該數據流只需是用來接納和發送數據,同步也分多客戶端和單個客戶端,假如分的詳細一點的話,還有客戶端的一條以及多條數據的狀況,假如是單個客戶端的多條數據的話,銜接客戶端之後,在樹立數據流的後面添加一個循環就可以了,假如是多個客戶端的話,在(2)後面加個循環就可以了。為了接納數據的效率,建議不論是同步還是異步,服務端都做成線程,詳細見Demo

(4)接納客戶端發送過去的數據(用緩存來接納)

byte[] buffer = new byte[BufferSize]; // BufferSize為緩存的大小

 int bytesRead; 

 try

 {

  lock (streamToClient)//為了保證數據的完好性以及平安性 鎖定數據流

   {

     bytesRead = streamToClient.Read(buffer, 0, BufferSize);

} 

(5)向銜接的客戶端發送數據

lock (streamToClient)

           {

           streamToClient.Write(buffer, 0, buffer.Length);//buffer為發送的字符數組         

} 

 (6)釋放數據流和TcpClient(以便下次的數據以及客戶端的收發)

streamToClient.Dispose();//釋放數據流中的數據

 remoteClient.Close();//釋放TcpClient實例 

客戶端

(1)   銜接服務器

TcpClient tcp = new TcpClient();

tcp.Connect(IP,Port);//依據服務器的IP地址和偵聽的端口銜接

if (tcp.Connected)

{

//銜接成功的音訊機制 詳細見DEMO

ShowGetData("成功銜接上了服務器:", this.strIP.Text.ToString());
 

 } 

這裡需求留意的是,不論是運用有參數的結構函數與服務器銜接,或許是經過Connect()辦法與服務器樹立銜接,都是同步辦法(或許說是阻塞的,英文叫block)。它的意思是說,客戶端在與服務端銜接成功、從而辦法前往,或許是服務端不存、從而拋出異常之前,是無法持續停止後繼操作的。這裡還有一個名為BeginConnect()的辦法,用於施行異步的銜接,這樣順序不會被阻塞,可以立刻執行前面的操作,這是由於能夠由於網絡擁塞等問題,銜接需求較長時間才干完成。網絡編程中有十分多的異步操作,凡事都是由簡入難,關於異步操作,我們前面再討論,如今只看同步操作。

(2)   樹立銜接服務端的數據流

NetworkStream streamToServer = tcp.GetStream(); 

(3)   接納和發送數據

//發送字符串

byte[] buffer = Encoding.Unicode.GetBytes(msg); //msg為發送的字符串  

 try

     {

       lock (streamToServer)
      {

      streamToServer.Write(buffer, 0, buffer.Length);   // 發往服務器

       }

     //接納字符串
       buffer = new byte[BufferSize];
       lock (streamToServer)

      {

        bytesRead = streamToServer.Read(buffer, 0, BufferSize);

      }

} 

1.2. 異步

絕對於同步,異步中的銜接,接納和發送數據的辦法都不一樣,都有一個回調函數,就是即便不能銜接或許接納不到數據,順序還是會不斷執行下去,假如銜接上了或許接到數據,順序會回到這個回調函數的中央重新往下執行。詳細見上面:

服務器:

1、 開啟偵聽接口

private TcpListener listener;        //監聽類

listener = new TcpListener(new IPEndPoint(IPAddress.Parse(ip), port));

listener.Start();//開啟偵聽,對銜接的客戶端的數目沒無限制

或許

listener.Start(int i);// 開啟偵聽,最多只能銜接i個客戶端數目 

2、 接納客戶端

listener.BeginAcceptSocket(clientConnect, listener);//異步承受客戶端的銜接懇求  clientConnect為銜接的回調函數

     /// <summary>

    /// 接納回調函數

    /// </summary>

    /// <param name="ar"></param>

    private void clientConnect(IAsyncResult ar)

    {

    try

      {
        TcpListener listener = (TcpListener)ar.AsyncState;
        //承受客戶的銜接,失掉銜接的Socket
        Socket client = listener.EndAcceptSocket(ar);

      }

      catch { }

    } 

3、 接納客戶端發送的數據

/// <summary> 

/// 異步接納數據

 /// </summary>

 private void receiveData(Socket client)

{

   // 調用異步辦法 BeginReceive 來告知 socket 如何接納數據
  IAsyncResult iar = client.BeginReceive(buffer, 0, BagSize, SocketFlags.None, out errorCode, receiveCallback, buffer);

      }

   }

    /// <summary>

    /// 接納數據回調函數

    /// </summary> 

    /// <param name="ar"></param>

    private void receiveCallback(IAsyncResult ar)

    {     
        //接納到的數據長度.
        int receLen = 0;

        try

        {
          receLen = client.EndReceive(ar, out errorCode);        

if (receLen > 0)

         {
           OnReceiveData(client);//接納到數據之後的處置函數

          }
        }
       catch {   }

      }
      else { }

    } 

4、接納成功之後,回發數據給客戶端

/// <summary>

/// 異步發送報文
/// </summary>

 /// <param name="data"></param>
 private void OnReceiveData (Socket socket)

{
     string strLogin = “succeed recived”;

byte[] data = Encoding.ASCII.GetBytes(strLogin);

 socket.BeginSend(data, 0, data.Length, SocketFlags.None, out errorCode, sendCallBack, socket);//異步發送數據

     }

      else

      { }

    }

/// <summary>

 /// 異步發送回調事情

 /// </summary>

 /// <param name="ar"></param>

private void sendCallBack(IAsyncResult ar)

    {

socket.EndSend(ar, out errorCode);

     } 

客戶端

1、銜接服務器

private TcpClient tcpcz = null

 tcpcz = new TcpClient()

 tcpcz.BeginConnect(ipaddress, Convert.ToInt32(port), new AsyncCallback(ConnectCallback), tcpcz);//依據服務器的IP地址和端口號 異步銜接服務器

 /// <summary>

/// 異步銜接的回調函數

 /// </summary>

 /// <param name="ar"></param>

 private void ConnectCallback(IAsyncResult ar)

    {

      TcpClient t = (TcpClient)ar.AsyncState;

      try

      {

        if (t.Connected)

        {

          t.EndConnect(ar);//函數運轉到這裡就闡明銜接成功

        }

        else

        {

        }

      }

      catch () {  }

    } 

2、發送和接納字符串

NetworkStream stream = tcp.GetStream();//創立於服務器銜接的數據流

        //發送字符串

  string strLogin = “this is socket example”;

  byte[] data = Encoding.ASCII.GetBytes(strLogin);

 stream.BeginWrite(data, 0, data.Length, new AsyncCallback(SendCallback),stream);//異步發送數據

 //接納字符串

  byte[] result = new byte[tcp.Available]; // tcp.Available為承受的字符串大小

  try

 {

   stream.BeginRead(result, 0, result.Length, new AsyncCallback(ReadCallback), stream);//異步承受服務器報答的字符串

  }

    catch { }

    string strResponse = Encoding.ASCII.GetString(result).Trim();//從服務器承受到的字符串

 }

  }

     catch ()

     {

     }

   } 

以上是這一段時間對socket的一些心得,希望對大家的學習有所協助,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved