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里面。