C#使用TcpListener与TcpClient实现简单聊天通信

苏见山
苏见山
发布时间:2026-10-14 | 7人浏览过
原创

本文将详细讲解如何在C# Windows Forms应用中实现一个基础的点对点聊天程序。核心逻辑包括服务器端的端口监听(TcpListener)与线程处理,以及客户端的连接(TcpClient)和数据流读写操作。文中将提供关键的代码片段说明具体的参数配置与方法调用。

核心原理与准备条件

要实现简单的文本聊天功能,需要明确两个角色的职责:服务器端负责持续监听特定IP和端口,等待客户端连接;客户端负责发起连接请求并发送数据。整个过程依赖于TCP协议的可靠连接特性。

  1. 依赖库:必须引入 System.Net.Sockets, System.Net, System.IO, 以及 System.Threading 命名空间。
  2. 关键类:
    • TcpListener:用于监听传入的连接请求。
    • TcpClient:用于连接服务器或作为已连接的实例进行数据传输。
    • NetworkStream:表示底层的网络数据流,所有IO操作都基于此流。
    • BinaryReader / BinaryWriter:方便地读取和写入字符串等数据类型。
  3. 运行顺序:启动服务器监听 → 客户端发起连接 → 双方通过流进行读写。

第1步:搭建服务器端ChatServer

服务器端的主要任务是开启监听并接受连接。由于接受连接和处理消息是阻塞操作,建议使用独立线程执行,以免界面卡顿。

1.1 初始化与配置

定义端口、IP地址及核心网络组件变量。以下示例使用了固定IP和端口号54321,实际部署时可改为动态获取本机IP。

using System.Net.Sockets;
using System.Net;
using System.IO;
using System.Threading;

public class ChatServer
{
    private int port = 54321; // 监听端口
    // 注意:实际应用中建议使用 Dns.GetHostName() 获取本机IP或 IPAddress.Any
    private IPAddress ip = IPAddress.Parse("10.20.30.40"); 
    
    private TcpListener tcpListener = null;
    private TcpClient tcpClient = null;
    private NetworkStream networkStream = null;
    private BinaryReader reader;
    private string getAllMsg = ""; // 用于存储接收到的消息
}

1.2 启动监听服务

在WinForm窗体的“开始监听”按钮点击事件中,实例化 TcpListener 并开始监听。同时创建一个新线程来处理客户端的接入请求。

// 假设这是界面上“开始监听”按钮的单击事件
private void btnStartListen_Click(object sender, EventArgs e)
{
    // 绑定IP和端口
    tcpListener = new TcpListener(ip, port);
    
    // 开始监听
    tcpListener.Start(); 
    
    // 创建专门用于接受客户端消息的线程
    Thread acceptClientMsgThread = new Thread(AcceptClientMsg);
    // 设置为后台线程,防止程序意外退出导致主线程阻塞
    acceptClientMsgThread.IsBackground = true;
    acceptClientMsgThread.Start();
}

1.3 接受连接与读取消息

AcceptTcpClient 是一个阻塞方法,会一直等待直到有客户端连接。一旦连接建立,即可获取网络流并进行循环读取。

private void AcceptClientMsg()
{
    try
    {
        // 等待并接受一个客户端连接
        tcpClient = tcpListener.AcceptTcpClient();
        
        if (tcpClient != null)
        {
            // 获取网络流
            networkStream = tcpClient.GetStream();
            // 创建二进制读取器
            reader = new BinaryReader(networkStream);
            
            // 循环读取客户端发来的信息
            while (true)
            {
                // ReadString 会自动读取长度前缀后跟随的字符串
                string msg = reader.ReadString();
                getAllMsg += msg;
                
                // 注意:在实际WinForm应用中,跨线程更新UI需要使用Invoke
                // txtShowClientMsg.Text = getAllMsg;
            }
        }
    }
    catch (Exception ex)
    {
        // 记录异常或提示用户断开
        Console.WriteLine(ex.Message);
    }
}

若服务器需要回复客户端,需在确保已获取到 networkStream 的前提下,实例化 BinaryWriter 并调用 Write 方法:

// 发送消息示例
string sendMsg = "Hello Client";
BinaryWriter writer = new BinaryWriter(networkStream);
writer.Write(sendMsg); // 需先调用 Flush()

第2步:搭建客户端ChatClient

客户端的核心功能是连接服务器,并通过同一根网络流进行双向通信。需要注意的是,TcpClient 实例既用于连接也用于维持状态。

2.1 发起连接

实例化 TcpClient 后,调用 Connect 方法指向服务器的IP和端口。成功后立即获取 NetworkStream。

using System.Net.Sockets;
using System.Net;
using System.IO;

public class ChatClient
{
    private int port = 54321;
    private IPAddress ip = IPAddress.Parse("10.20.30.40");
    
    private TcpClient tcpClient = null;
    private NetworkStream networkStream = null;
    private BinaryWriter writer;
    // private BinaryReader reader; // 如果需要接收服务端消息则解开注释
}

2.2 建立连接动作

对应窗体上的“连接服务器”按钮:

private void btnStartConnect_Click(object sender, EventArgs e)
{
    try
    {
        tcpClient = new TcpClient();
        // 连接到指定IP和端口
        tcpClient.Connect(ip, port);
        
        // 获取网络流,用于后续读写
        networkStream = tcpClient.GetStream();
    }
    catch (Exception ex)
    {
        MessageBox.Show("连接失败: " + ex.Message);
    }
}

2.3 发送消息

连接稳定后,初始化 BinaryWriter 并发送文本。注意:由于 BinaryWriter 和 BinaryReader 共享底层流,如果两端都有收发消息需求,需分别实例化对应的读/写对象。

private void btnSend_Click(object sender, EventArgs e)
{
    // 假设获取输入框内容
    string sendMsg = txtSendMsg.Text;
    
    if (!string.IsNullOrEmpty(sendMsg) && networkStream != null)
    {
        // 如果未初始化writer,在此处初始化
        if (writer == null)
        {
            writer = new BinaryWriter(networkStream);
        }
        
        // 发送字符串
        writer.Write(sendMsg);
        writer.Flush(); // 确保数据写入缓冲区
        
        // 清空输入框
        txtSendMsg.Clear();
    }
}

完成判断与注意事项

连接成功判定:
1. 服务器端 btnStartListen_Click 无报错抛出。
2. 客户端 btnStartConnect_Click 执行完毕,且未进入Catch块。
3. 此时客户端发出的消息会在服务器端的 getAllMsg 变量或UI控件中体现。

潜在问题排查:
- 防火墙拦截:确保服务器所在主机允许端口(如54321)入站流量。 - IP地址匹配:客户端填写的IP必须是服务器当前有效的本地IP(内网测试通常用127.0.0.1或局域网IP),而非公网IP,否则在局域网调试时会连接超时。 - 并发限制:上述简易示例仅支持单客户端连接。若需多客户端,服务器端需在 AcceptClientMsg 外部循环调用 AcceptTcpClient 并为每个新连接分配独立的线程。

以上就是基于C# Socket编程实现简单聊天程序的详细内容,更多关于C# TcpListener与TcpClient网络通信的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表