TcpClient和以前學過的對象,相對關系示意圖如下:
借助有連接的特性,它封裝了很多需要一起使用的對象,用起來也更加方便。
作為服務端時,它一般配合TcpListener使用。
由監聽者創建的所有客戶端,都使用與監聽者相同的ipendpoint。(實現上,可以理解為不同的socket指向相同的ipendpoint)
例:
說明:服務端有一個監聽者(TcpListener),接收到連接請求后,建立連接給一個客戶端(TcpClient)。
利用流讀取器(StreamReader)獲取傳遞過來的信息並顯示。
客戶端建立一個客戶端對象(TcpClient),連接服務端后就可以利用流寫入對象(StreamWriter)發送數據。
代碼如下:
服務端:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Net; 7 using System.Net.Sockets; 8 using System.IO; 9 10 namespace ConsoleApp1 11 { 12 class Program 13 { 14 static void Main(string[] args) 15 { 16 TcpListener listener = new TcpListener(IPAddress.Any, 9000); 17 TcpClient client = new TcpClient(); 18 StreamReader sr; 19 string msg; 20 listener.Start(); 21 client = listener.AcceptTcpClient(); 22 sr = new StreamReader(client.GetStream()); 23 do 24 { 25 msg = sr.ReadLine(); 26 Console.WriteLine(msg); 27 } while (msg.ToLower()!="exit"); 28 } 29 } 30 }
客戶端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApp2 { class Program { static void Main(string[] args) { TcpClient tcp = new TcpClient(); string msg; IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9000); tcp.Connect(iPEndPoint); StreamWriter sw = new StreamWriter(tcp.GetStream()); do { msg = Console.ReadLine(); sw.WriteLine(msg); sw.Flush(); } while (msg.ToLower()!="exit"); } } }
運行效果:
在此基礎智商,兩邊互相收發,也很簡單。
服務端代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApp1 { class Program { static void Main(string[] args) { TcpListener listener = new TcpListener(IPAddress.Any, 9000); TcpClient client; StreamReader reader; StreamWriter writer; string msg; listener.Start(); client= listener.AcceptTcpClient(); reader = new StreamReader(client.GetStream()); writer = new StreamWriter(client.GetStream()); do { Console.WriteLine("等待接收數據:"); msg=reader.ReadLine(); Console.WriteLine(msg); Console.WriteLine("等待發送數據:"); msg = Console.ReadLine(); writer.WriteLine(msg); writer.Flush(); } while (msg.ToLower()!="exit"); } } }
客戶端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApp2 { class Program { static void Main(string[] args) { TcpClient client=new TcpClient(); StreamReader reader; StreamWriter writer; string msg; client.Connect(IPAddress.Parse("127.0.0.1"),9000); reader = new StreamReader(client.GetStream()); writer = new StreamWriter(client.GetStream()); do { Console.WriteLine("等待發送數據:"); msg = Console.ReadLine(); writer.WriteLine(msg); writer.Flush(); Console.WriteLine("等待接收數據:"); msg = reader.ReadLine(); Console.WriteLine(msg); } while (msg.ToLower() != "exit"); } } }
運行效果:
當啟用另外一個單獨的線程去接收數據的時候,發送和接收就可以互不干擾了。
服務端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApp1 { class Program { static void Main(string[] args) { TcpListener listener = new TcpListener(IPAddress.Any, 9000); TcpClient client; StreamWriter writer; string msg; listener.Start(); client= listener.AcceptTcpClient(); Task t = new Task(getMessage, client); t.Start(); writer = new StreamWriter(client.GetStream()); do { Console.WriteLine("等待發送數據:"); msg = Console.ReadLine(); writer.WriteLine(msg); writer.Flush(); } while (msg.ToLower()!="exit"); } static void getMessage(object tcp) { StreamReader reader; TcpClient client = (TcpClient)tcp; reader = new StreamReader(client.GetStream()); string msg; do { Console.WriteLine("等待接收數據:"); msg = reader.ReadLine(); Console.WriteLine(msg); } while (msg.ToLower() != "exit"); } } }
客戶端:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApp1 { class Program { static void Main(string[] args) { TcpClient client=new TcpClient(); StreamWriter writer; string msg; client.Connect(IPAddress.Parse("127.0.0.1"), 9000); Task t = new Task(getMessage, client); t.Start(); writer = new StreamWriter(client.GetStream()); do { Console.WriteLine("等待發送數據:"); msg = Console.ReadLine(); writer.WriteLine(msg); writer.Flush(); } while (msg.ToLower() != "exit"); } static void getMessage(object tcp) { StreamReader reader; TcpClient client = (TcpClient)tcp; reader = new StreamReader(client.GetStream()); string msg; do { Console.WriteLine("等待接收數據:"); msg = reader.ReadLine(); Console.WriteLine(msg); } while (msg.ToLower() != "exit"); } } }
運行結果:
思考:重復監聽,連接多客戶端。在任意接收線程收到消息后,向各客戶端群發消息。即構建聊天室程序。
提示:多客戶端可以存在List里面。