万金流
以码会友。 吾Q:578751655。 水平有限,轻喷,谢!
随笔 - 189,  文章 - 0,  评论 - 7,  阅读 - 14万

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

 

posted on   万金流  阅读(2604)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现

点击右上角即可分享
微信分享提示