熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

用C#實現基於TCP協議的網絡通訊

2013-11-13 10:01:22  來源: .NET編程 
TCP協議是一個基本的網絡協議基本上所有的網絡服務都是基於TCP協議的如HTTPFTP等等所以要了解網絡編程就必須了解基於TCP協議的編程然而TCP協議是一個龐雜的體系要徹底的弄清楚它的實現不是一天兩天的功夫所幸的是在net framework環境下我們不必要去追究TCP協議底層的實現一樣可以很方便的編寫出基於TCP協議進行網絡通訊的程序
 
  要進行基於TCP協議的網絡通訊首先必須建立同遠程主機的連接連接地址通常包括兩部分——主機名和端口 就是主機名指主機的端口當然主機名也可以用IP地址代替當連接建立之後就可以使用這個連接去發送和接收數據包TCP協議的作用就是保證這些數據包能到達終點並且能按照正確的順序組裝起來
 
  在net framework的類庫(Class Library)中提供了兩個用於TCP網絡通訊的類分別是TcpClient和TcpListener由其英文意義顯而易見TcpClient 類是基於TCP協議的客戶端類而TcpListener是服務器端監聽(Listen)客戶端傳來的連接請求TcpClient類通過TCP協議與服務器進行通訊並獲取信息它的內部封裝了一個Socket類的實例這個Socket對象被用來使用TCP協議向服務器請求和獲取數據因為與遠程主機的交互是以數據流的形式出現的所以傳輸的數據可以使用net framework中流處理技術讀寫在我們下邊的例子中你可以看到使用NetworkStream類操作數據流的方法
 
  在下面的例子中我們將建立一個時間服務器包括服務器端程序和客戶端程序服務器端監聽客戶端的連接請求建立連接以後向客戶端發送當前的系統時間
 
  先運行服務器端程序下面截圖顯示了服務器端程序運行的狀況
 
  然後運行客戶端程序客戶端首先發送連接請求到服務器端服務器端回應後發送當前時間到客戶端這是客戶端程序的截圖
 
  發送完成後服務器端繼續等待下一次連接
 
  通過這個例子我們可以了解TcpClient類的基本用法要使用這個類必須使用SystemNetSocket命名空間本例用到的三個命名空間如下
 
  

  using System;
  using SystemNetSockets;
  using SystemText;//從字節數組中獲取字符串時使用該命名空間中的類
  //首先討論一下客戶端程序開始我們必須初始化一個TcpClient類的實例

  TcpClient client = new TcpClient(hostName portNum);
  //然後使用TcpClient類的GetStream()方法獲取數據流並且用它初始化一個NetworkStream類的實例

  NetworkStream ns = clientGetStream();

 
  注意當使用主機名和端口號初始化TcpClient類的實例時直到跟服務器建立了連接這個實例才算真正建立程序才能往下執行如果因為網絡不通服務器不存在服務器端口未開放等等原因而不能連接程序將拋出異常並且中斷執行
 
  建立數據流之後我們可以使用NetworkStream類的Read()方法從流中讀取數據使用Write()方法向流中寫入數據讀取數據時首先應該建立一個緩沖區具體的說就是建立一個byte型的數組用來存放從流中讀取的數據Read()方法的原型描述如下
 
  public override int Read(in byte[] bufferint offsetint size)
 
  buffer是緩沖數組offset是數據(字節流)在緩沖數組中存放的開始位置size是讀取的字節數目返回值是讀取的字節數在本例中簡單地使用該方法來讀取服務器反饋的信息
 
  

  byte[] bytes = new byte[];//建立緩沖區
  int bytesRead = nsRead(bytes bytesLength);//讀取字節流
 // 然後顯示到屏幕上

  ConsoleWriteLine(EncodingASCIIGetString(bytesbytesRead));
  //最後不要忘記關閉連接

  clientClose();

  下面是本例完整的程序清單
 
  

  

  using System;
  using SystemNetSockets;
  using SystemText;
  namespace TcpClientExample
  {
    public class TcpTimeClient
    {
      private const int portNum = ;//服務器端口可以隨意修改
      private const string hostName = ;//服務器地址指本機

  [STAThread]
      static void Main(string[] args)
      {
        try
        {
          ConsoleWrite(Try to connect to +hostName+:+portNumToString()+\r\n);
          TcpClient client = new TcpClient(hostName portNum);
          NetworkStream ns = clientGetStream();
          byte[] bytes = new byte[];
          int bytesRead = nsRead(bytes bytesLength);
          ConsoleWriteLine(EncodingASCIIGetString(bytesbytesRead));
          clientClose();
          ConsoleReadLine();//由於是控制台程序故為了清楚的看到結果可以加上這句

  }
        catch (Exception e)
        {
          ConsoleWriteLine(eToString());
        }
      }
    }
  }

  上面這個例子清晰地演示了客戶端程序的編寫要點下面我們討論一下如何建立服務器程序這個例子將使用TcpListener類號端口監聽一旦有客戶端連接將立即向客戶端發送當前服務器的時間信息
 
  TcpListener的關鍵在於AcceptTcpClient()方法該方法將檢測端口是否有未處理的連接請求如果有未處理的連接請求該方法將使服務器同客戶端建立連接並且返回一個TcpClient對象通過這個對象的GetStream方法建立同客戶端通訊的數據流事實上 TcpListener類還提供一個更為靈活的方法AcceptSocket()當然靈活的代價是復雜對於比較簡單的程序 AcceptTcpClient()已經足夠用了此外TcpListener類提供Start()方法開始監聽提供Stop()方法停止監聽
 
  首先我們使用端口初始化一個TcpListener實例並且開始在端口監聽
 
  

  

  private const int portNum = ;
  TcpListener listener = new TcpListener(portNum);
  listenerStart();//開始監聽
  //如果有未處理的連接請求使用AcceptTcpClient方法進行處理並且獲取數據流

  TcpClient client = listenerAcceptTcpClient();
  NetworkStream ns = clientGetStream();
  //然後獲取本機時間並保存在字節數組中使用NetworkStreamWrite()方法寫入數據流然後客戶端就可以通過Read()方法從數據流中獲取這段信息

  byte[] byteTime = EncodingASCIIGetBytes(DateTimeNowToString());
  nsWrite(byteTime byteTimeLength);
  nsClose();//不要忘記關閉數據流和連接
  clientClose();

  服務器端程序完整的程序清單如下
 
    using System;
  using SystemNetSockets;
  using SystemText;
  namespace TimeServer
  {
    class TimeServer
    {
      private const int portNum = ;
      [STAThread]
      static void Main(string[] args)
      {
        bool done = false;
        TcpListener listener = new TcpListener(portNum);
        listenerStart();
        while (!done)
        {
          ConsoleWrite(Waiting for connection);
          TcpClient client = listenerAcceptTcpClient();
          ConsoleWriteLine(Connection accepted);
          NetworkStream ns = clientGetStream();
          byte[] byteTime = EncodingASCIIGetBytes(DateTimeNowToString());
          try
          {
            nsWrite(byteTime byteTimeLength);
            nsClose();
            clientClose();
          }
          catch (Exception e)
          {
            ConsoleWriteLine(eToString());
          }
        }
        listenerStop();
      }
    }
  }
 
  把上面兩段程序分別編譯運行OK我們已經用C#實現了基於TCP協議的網絡通訊怎麼樣?很簡單吧!
 
  使用上面介紹的基本方法我們可以很容易的編寫出一些很有用的程序如FTP電子郵件收發點對點即時通訊等等你甚至可以自己編制一個QQ
 


From:http://tw.wingwit.com/Article/program/net/201311/12305.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.