C#開源類庫SimpleTCP使用方法
簡介
工作中經常遇到需要實現TCP客戶端或服務端的時候,如果每次都自己寫會很麻煩且無聊,使用SuperSocket庫又太大瞭。這時候就可以使用SimpleTCP瞭,當然僅限於C#語言。
SimpleTCP是一個簡單且非常有用的 .NET 庫,用於處理啟動和使用 TCP 套接字(客戶端和服務器)的重復性任務,使用起來非常方便、代碼也少。它的內部不是直接使用的Socket,而是在TcpClient的基礎上進行瞭再次封裝,接口更簡單、明瞭。
它的主要特點如下:
- 源碼簡單:源碼就幾個類,每個類也不大,在瞭解TcpClient用法的基礎上不需要註釋就可以看懂。
- 功能單一:不像其它庫一樣功能繁多,它隻專註於實現簡單的TCP客戶端、服務端,使用起來不用擔心增加系統的復雜性。
- 使用簡單:後面的示例會具體講解,啟動一個客戶端或服務端隻需要幾行代碼,想擴展功能也很簡單。
說一下它的不足之處(在我看來完全可以接受):
- 已停止更新:最後更新時間是2017年,不過庫的功能比較簡單、單一,也沒那麼多更新的內容。
- 性能不是最優的:底層是基於TcpClient的,性能註定不會太高,但能用TcpClient的地方都可以用它。
使用方法
在項目中直接引用SimpleTCP.dll即可, dll文件可以通過NuGet安裝或從github下載源碼編譯。
SimpleTCP內部有一個特殊字符分割字符串的協議可以直接使用,也可以在DataReceived事件處理程序中實現自己的協議。
實現客戶端
實現一個客戶端的代碼如下:
//初始化 var client = new SimpleTcpClient(); //設置編碼格式,默認是UTF8 client.StringEncoder = System.Text.ASCIIEncoding.ASCII; //設置分隔符,默認是0x13 client.Delimiter = Encoding.ASCII.GetBytes("\r")[0]; //收到分割數據的事件,遇到分隔符就會觸發事件 client.DelimiterDataReceived += (sender, msg) => { Console.WriteLine("DelimiterStr-"+DateTime.Now.ToString()+ msg.MessageString); }; //收到數據的事件,可以在這裡實現自己的協議 client.DataReceived += (sender, msg) => { //字節數組 Console.WriteLine("Data:"+BitConverter.ToString(msg.Data)); //字符串消息 Console.WriteLine("ReceivedStr:" + msg.MessageString); };
DelimiterDataReceived和DataReceived內部使用瞭兩個不同的字節鏈表,解析起來互不影響。這兩個事件的處理程序中盡量不要做耗時的操作,否則會影響後續的數據接收。
SimpleTCP沒有心跳、重連功能,也沒找到反饋客戶端連接狀態的屬性(不建議使用內部TcpClient的連接狀態)。我們可以直接擴展這些功能,代碼如下:
bool exit = false; bool connected = false; Task.Factory.StartNew(() => { while (!exit) { try { if (connected) { //發送心跳 client.Write(""); Task.Delay(10000).Wait(); } else { //斷線重連 client.Connect("127.0.0.1", 4196); connected = true; Task.Delay(1000).Wait(); } } catch (Exception) { connected = false; client.Disconnect(); } } }, TaskCreationOptions.LongRunning);
把上面的代碼按順序復制到控制臺的Main函數中,然後加入下面的代碼就可以收發數據瞭:
while (true) { string strLine = Console.ReadLine(); if (strLine == "esc") { exit = true; client.Disconnect(); return; } if (connected) { //獲取服務端回復的消息,最多等待3秒,收到消息時會提前返回 //也可以使用Write、WriteLine方法發送數據,WriteLine會自動在後面加上設置的分隔符 var replyMsg = client.WriteLineAndGetReply(strLine, TimeSpan.FromSeconds(3)); if (replyMsg != null) { Console.WriteLine(replyMsg); } } }
註:WriteLineAndGetReply內部使用的是DataReceived,不會自動去除分隔符。
實現服務端
服務端功能比較簡單,把收到分割數據加工後返回客戶端,代碼如下:
//初始化 var server = new SimpleTcpServer(); //設置編碼格式,默認是UTF8 server.StringEncoder = System.Text.ASCIIEncoding.ASCII; server.Delimiter = Encoding.ASCII.GetBytes("\r")[0]; //分割數據接收事件 server.DelimiterDataReceived += (sender, msg) => { Console.WriteLine(msg.TcpClient.Client.RemoteEndPoint.ToString()+":" + msg.MessageString); msg.ReplyLine("Reply-" + msg.MessageString); }; //數據接收數據 server.DataReceived += (sender, msg) => { Console.WriteLine(msg.TcpClient.Client.RemoteEndPoint.ToString() + ":" + msg.MessageString); }; //客戶端連接事件 server.ClientConnected += (sender, msg) => { Console.WriteLine("ClientConnected:" + msg.Client.RemoteEndPoint.ToString()); }; //客戶端斷開事件 server.ClientDisconnected += (sender, msg) => { Console.WriteLine("ClientDisconnected:" + msg.Client.RemoteEndPoint.ToString()); }; //開始監聽 server.Start(4196); //監聽的IP var listeningIps = server.GetListeningIPs(); //監聽的V4Ip var listeningV4Ips = server.GetListeningIPs().Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); Task.Factory.StartNew(() => { while (true) { //連接數監控 int clientsConnected = server.ConnectedClientsCount; Console.WriteLine("當前連接的客戶端數:" + clientsConnected); Task.Delay(10000).Wait(); } }, TaskCreationOptions.LongRunning); Console.ReadLine(); //停止監聽 server.Stop(); Console.WriteLine("停止服務端!"); Console.ReadLine();
總結
上面的代碼主要為瞭展示庫的功能,實際使用時可能就幾行代碼,性能要求不高的項目都可以使用。
項目和庫的源碼鏈接如下:
鏈接: https://pan.baidu.com/s/1NgW4CQsU-1BJGgJHg8X2Fg 提取碼: 7vgf
鏈接: https://pan.baidu.com/s/1_2Gr83mkygHdN6B3KIx56w 提取碼: 5kdh
到此這篇關於C#開源類庫SimpleTCP的文章就介紹到這瞭,更多相關C#開源類庫內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!