C#網路程式設計(二)------多執行緒socket例項
阿新 • • 發佈:2019-01-31
伺服器端程式碼:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net;
- using System.Net.Sockets;
- using System.Threading;
- namespace multithreadservTest
- {
- class Threadtcpserver
- {
-
/* 本程式中採用了多執行緒技術,可以應付多客戶的需求。首先,程式的主執行緒也就是程式的入口即Main()函式,
- * 當執行到Accept方法時,執行緒變會阻塞;當有新連線時,就建立相應的訊息服務執行緒。而主程式則繼續進行監聽,
- * 檢查有沒有新的連線進入。如果客戶端有向伺服器連線的請求,那麼就把連線控制代碼傳遞給接收的套接字。由於執行緒
- * 的排程和切換是非常快的,快得足以讓我們分辨不出程式的執行順序,所以從巨集觀上來講,可以說程式是並行執行
- * 的。但事實上,從微觀的角度上說,只是cpu飛快地排程執行緒,讓我們感覺好像可以同時接收連線和處理訊息一樣,
-
* 但在一個時刻,只有一個執行緒是處於執行狀態的。
- */
- /// <summary>
- /// 下面這段程式碼的業務邏輯是:
- /// (1)建立套接字server,並將其與本地終結點iep進行繫結。然後,在13000埠上監聽是否
- 有新的客戶端進行連線
- /// (2)在無限迴圈中有一個阻塞的方法Accept,該方法直到有新客戶端連線到伺服器上時,把
- 客戶端的套接字資訊傳遞給client物件。否則,將阻塞 直到有客戶機進行連線。
-
/// (3)ClientThread類負責客戶端與伺服器端之間的通訊。先把客戶端的套接字控制代碼傳遞給
- /// 負責訊息服務的ClientThread類。然後,把ClientThread類 的ClientService方
- 法委託給執行緒,並啟動執行緒。
- /// </summary>
- private Socket server;
- public Threadtcpserver()
- {
- //初始化IP地址
- IPAddress local=IPAddress.Parse("192.168.5.187");
- IPEndPoint iep = new IPEndPoint(local, 13000);
- server = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
- ProtocolType.Tcp);
- //將套接字與本地終結點繫結
- server.Bind(iep);
- //在本地13000埠號上進行監聽
- server.Listen(20);
- Console.WriteLine("等待客戶機進行連線......");
- while (true)
- {
- //得到包含客戶端資訊的套接字
- Socket client = server.Accept();
- //建立訊息服務執行緒物件
- ClientThread newclient = new ClientThread(client);
- //把ClientThread類的ClientService方法委託給執行緒
- Thread newthread = new Thread(new ThreadStart(newclient.ClientService));
- //啟動訊息服務執行緒
- newthread.Start();
- }
- }
- /// <summary>
- /// (1)在建構函式中得到接收到的客戶套接字client,以後就通過service控制代碼處理訊息的接收
- /// 和傳送。
- /// (2)ClientService方法是委託給執行緒的,此方法進行訊息的處理工作。在這裡實現的功能是,
- /// 先從客戶端接收一條訊息,然後把這條訊息轉換為大寫字母,並立即傳送一條應答的訊息,
- /// 也就是所謂的echo技術,通常用來進行訊息之間的傳遞。
- /// (3)還有就是通過connections變數來記錄活動的連線數。當有新增連線或斷開連線的情況發
- /// 生時,都會體現出connections的變化。
- /// </summary>
- publicclass ClientThread
- {
- //connections變量表示連線數
- publicstaticint connections = 0;
- public Socket service;
- int i;
- //建構函式
- public ClientThread(Socket clientsocket)
- {
- //service物件接管對訊息的控制
- this.service = clientsocket;
- }
- publicvoid ClientService()
- {
- String data = null;
- byte[] bytes = newbyte[1024];
- //如果Socket不是空,則連線數加1
- if (service != null)
- {
- connections++;
- }
- Console.WriteLine("新客戶連線建立:{0}個連線數", connections);
- while((i=service.Receive(bytes))!=0)
- {
- data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
- Console.WriteLine("收到的資料:{0}", data);
- //處理客戶端發來的訊息,這是轉化為大寫字母
- data = data.ToUpper();
- byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
- //傳送一條應答訊息
- service.Send(msg);
- Console.WriteLine("傳送的資料:{0}", data);
- }
- //關閉套接字
- service.Close();
- connections--;
- Console.WriteLine("客戶關閉連線:{0}個連線數", connections);
- }
- /// <summary>
- /// Main函式十分簡單,生成和一個Threadtcpserver例項,然後建構函式就會一步一步地
- /// 展開,開始執行具體的業務邏輯。
- /// </summary>
- /// <param name="args"></param>
- staticvoid Main(string[] args)
- {
- Threadtcpserver instance = new Threadtcpserver();
- }
- }
- }
- }
客戶端程式碼:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Net;
- using System.Net.Sockets;
- namespace multithreadclientTest
- {
- class Program
- {
- /// <summary>
- /// 本程式程式碼的主要功能:
- /// (1)建立套接字,並通過connect方法連線到本地終結點。當連線建立以後,便可以與伺服器進
- /// 行通訊了。
- /// (2)在客戶端上等待使用者輸入一條訊息,該訊息會發送到伺服器建立的訊息服務執行緒上
- /// 的ClientService 方法上進行處理。在將該訊息轉化為大寫字母后,發還給客戶端。
- /// 這是一個echo技術。如果在控制檯上輸入exit 接斷開與伺服器之間的連線。
- /// </summary>
- /// <param name="args"></param>
- staticvoid Main(string[] args)
- {
- Socket client;
- byte[] buf = newbyte[1024];
- string input;
- IPAddress local = IPAddress.Parse("192.168.5.187");
- IPEndPoint iep = new IPEndPoint(local, 13000);
- try
- {
- client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
- ProtocolType.Tcp);
- client.Connect(iep);
- }
- catch (SocketException)
- {
- Console.WriteLine("無法連線到伺服器!");
- return;
- }
- finally
- {
- }
- while (true)
- {
- //在控制檯上輸入一