程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#的Socket程序(TCP)(2)

C#的Socket程序(TCP)(2)

編輯:關於C語言

基本步驟比較簡單:

建立本機的IPEndPoint對象,表示以本機為服務器,在指定端口偵聽;

然後綁定到一個偵聽Socket上;

進入while循環,等待新的聯接;

如果有新的聯接,那麼建立新的socket來對應這個聯接的會話。

值得注意的就是這一句聯接代碼:listener.Accept()。執行這一句的時候,程序就在這個地方等待,直到有新的聯檢請求的時候程序才會執行下一句。這是同步執行,當然也可以異步執行。

新的聯接Socket建立了(Accept之後),對於這些新的socket該怎麼辦呢?他們依然是一個循環等待,所以依然需要建立新的Thread給這些Socket去處理會話(接收/發送消息),而這個Thread就要接收參數了。

Thread本身是不能接收參數的,為了讓它可以接收參數,可以采用定義新類,添加參數作為屬性的方法來解決。

因為每一個Socket是一個Connection周期,所以我定義了這麼一個類public class Connection。這個類至少有這樣一個構造函數public Connection(Socket socket); 之所以這麼做,就是為了把Socket參數傳給這個Connection對象,然後好讓Listener啟動這個Thread的時候,Thread可以知道他正在處理哪一個Socket。

具體處理的方法:(在Listener的StartListening函數,ocket connection = listener.Accept();之後)

Connection gpsCn = new Connection(connection);
          //each socket will be wait for data. keep the connection.
          Thread thread = new Thread(new ThreadStart(gpsCn.WaitForSendData));
          thread.Name = connection.RemoteEndPoint.ToString();
          thread.Start();

如此一來,這個新的socket在Accept之後就在新的Thread中運行了。

3:Connection的會話處理

建立了新的Connection(也就是socket),遠程就可以和這個socket進行會話了,無非就是send和receive。

現在先看看怎麼寫的這個線程運行的Connection. WaitForSendData函數

while (true)
      {
        bytes = new byte[1024];
        string data = "";
        //systm will be waiting the msg of receive envet. like Accept();
        //here will be suspended while waiting for socket income msg.
        int bytesRec = this._connection.Receive(bytes);
        _lastConnectTime = DateTime.Now;
        if (bytesRec == 0)//close envent
        {
          Logger.Log("Close Connection", _connection.RemoteEndPoint.ToString());
          break;
        }
        data += Encoding.ASCII.GetString(bytes, 0, bytesRec);
        //…….handle your data.
       }

可以看到這個處理的基本步驟如下:

執行Receive函數,接收遠程socket發送的信息;

把信息從字節轉換到string;

處理該信息,然後進入下一個循環,繼續等待socket發送新的信息。

值得注意的有幾個:

1:Receive函數。這個函數和Listener的Accept函數類似。在這個地方等待執行,如果沒有新的消息,這個函數就不會執行下一句,一直等待。

2:接收的是字節流,需要轉化成字符串

3:判斷遠程關閉聯接的方式

4:如果對方的消息非常大,還得循環接收這個data。

4:如何管理這些聯接(thread)

通過上邊的程序,基本上可以建立一個偵聽,並且處理聯接會話。但是如何管理這些thread呢?不然大量產生thread可是一個災難。

管理的方法比較簡單,在Listener裡面我定義了一個靜態的哈希表(static public Hashtable Connections=new Hashtable();),存儲Connection實例和它對應的Thread實例。而connection中也加入了一個最後聯接時間的定義(private DateTime _lastConnectTime;)。在新鏈接建立的時候(Listener的Accept()之後)就把Connection實例和Thread實例存到哈希表中;在Connection的Receive的時候修改最後聯接時間。這樣我們就可以知道該Connection在哪裡,並且會話是否活躍。

然後在Winform程序裡頭可以管理這些會話了,設置設置超時。

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