C# asynchronous TcpListener

本文介绍了使用异步方式监听TCP连接并处理消息的过程,包括客户端连接管理、消息读取和事件触发机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyConnection.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace AsyncListener
{
    class MyConnection
    {
        public delegate void HandleMessageEvent(TcpClient client, string message);

        private TcpClient _client;
        private NetworkStream _stream;
        private byte[] _buffer;
        private static int _bufsize = 1024;
        private StringBuilder _msg = new StringBuilder();

        public event HandleMessageEvent MessageArrive = null;

        public MyConnection(TcpClient client)
        {
            _client = client;
            _stream = _client.GetStream();
            _buffer = new byte[_bufsize];
        }

        public void Process()
        {
            _stream.BeginRead(_buffer, 0, _buffer.Length, OnRead, null);
        }

        private void OnRead(IAsyncResult ar)
        {
            int count = _stream.EndRead(ar);
            if (count > 0)
            {
                string value = Encoding.ASCII.GetString(_buffer, 0, count);
                foreach (char ch in value)
                {
                    if (ch == '\n')
                    {
                        if (_msg.Length > 0)
                        {
                            if (_msg[_msg.Length - 1] == '\r') _msg.Remove(_msg.Length - 1, 1);
                            if (MessageArrive != null) MessageArrive(_client, _msg.ToString());
                            _msg.Clear();
                        }
                    }
                    else
                        _msg.Append(ch);
                }
            }
            _stream.BeginRead(_buffer, 0, _buffer.Length, OnRead, null);
        }
    }
}


MyListener.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace AsyncListener
{
    class MyListener
    {
        private TcpListener _server;
        private int _port;
        private Dictionary<string, MyConnection> _clientMap = new Dictionary<string, MyConnection>();

        public event MyConnection.HandleMessageEvent ClientMessageArrive = null;

        public MyListener(int port)
        {
            _port = port;
            _server = new TcpListener(_port);
        }

        public void Start()
        {
            _server.Start();
            _server.BeginAcceptTcpClient(OnAccept, _server);
        }

        private void OnAccept(IAsyncResult ar)
        {
            TcpClient client = _server.EndAcceptTcpClient(ar);
            Console.WriteLine("Accept client from " + client.Client.RemoteEndPoint.ToString());
            MyConnection conn = new MyConnection(client);
            conn.MessageArrive += ClientMessageArrive;

            _clientMap.Add(client.Client.RemoteEndPoint.ToString(), conn);

            conn.Process();

            _server.BeginAcceptTcpClient(OnAccept, _server);
        }

    }
}

Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace AsyncListener
{
    class Program
    {
        static void MsgArrive(TcpClient client, string msg)
        {
            Console.WriteLine("msg {0} from {1}", msg, client.Client.RemoteEndPoint.ToString());
        }

        static void Main(string[] args)
        {
            MyListener listener = new MyListener(12345);
            listener.ClientMessageArrive += MsgArrive;
            listener.Start();
            Console.WriteLine("Listen on port 12345");

            Console.ReadLine();
        }
    }
}









### C# 中基于 TCP 的高性能通信协议实现 在 C# 开发环境中,TCP 协议的高效实现依赖于 `Socket` 编程模型及其扩展类如 `TcpListener` 和 `TcpClient`。这些工具不仅提供对低级网络操作的支持,还允许开发者通过异步编程模式来提高程序性能和响应能力。 #### 使用 Socket 实现高性能 TCP 通信 为了构建高性能的 TCP 客户端和服务端,在设计阶段应考虑以下几个方面: 1. **异步 I/O 操作** 异步方法能够显著减少线程阻塞时间并释放资源用于其他任务。C# 提供了多种方式支持异步编程,例如 `async/await` 关键字以及传统的回调函数接口。对于大规模并发连接的应用场景,推荐采用事件驱动型异步套接字 (Event-based Asynchronous Pattern, EAP)[^3] 或者 Task 并行库 (TPL) 来管理输入输出流。 2. **缓冲区优化** 数据读写过程中合理设置缓冲大小有助于降低内存分配频率从而改善整体吞吐量。通常建议预定义固定长度的数据块作为消息单位,并配合分片重组逻辑完成大文件传输等功能需求。 以下是简单的服务端代码片段展示如何监听来自多个客户端的消息请求并通过非同步手段回复确认信息: ```csharp using System; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; public class AsyncTcpServer { private const int PortNumber = 8080; public static async Task StartListening() { try{ var listener = new TcpListener(System.Net.IPAddress.Any ,PortNumber); listener.Start(); while(true){ Console.WriteLine("Waiting for a connection..."); using(var client = await listener.AcceptTcpClientAsync()){ HandleClient(client).Wait(); } } }catch(Exception e){ Console.WriteLine($"Error : {e.Message}"); } } private static async Task HandleClient(TcpClient tcpClient){ NetworkStream stream = null ; try{ byte[] buffer=new Byte[256]; String data=""; stream=tcpClient.GetStream(); do{ Int32 bytes=await stream.ReadAsync(buffer,0,buffer.Length); data+=Encoding.ASCII.GetString(buffer,0,bytes); if(data.Contains("QUIT")){ break ; } string responseMessage=$"Echoed:{data}"; byte [] responseData= Encoding.ASCII.GetBytes(responseMessage ); await stream.WriteAsync(responseData,0,responseData.Length ); }while(stream.DataAvailable ); }finally{ if(stream !=null ){ stream.Close(); } } } } ``` 此示例仅作教学用途,实际生产环境还需加入更多健壮性的考量因素比如超时控制、异常捕获等措施确保系统的稳定性。 --- #### 性能调优策略 除了上述提到的技术要点外,还有几个额外的方向可以帮助进一步增强基于 TCP 的 C# 应用性能: - 利用多核处理器优势 – 如果目标平台具备足够的计算资源,则可以通过引入线程池或者专门的任务调度器充分利用硬件加速效果; - 减少序列化开销 – 当频繁交换复杂结构体的时候,挑选合适的编码解码方案至关重要,像 Protobuf 这样的二进制格式往往比 JSON 更紧凑也更快解析; - 调整操作系统参数 – 修改诸如最大半开放连接数之类的系统配置项可能也会带来意想不到的好处; 最后值得注意的是虽然本文重点讨论了有关 C# 下 TCP 高效实践的内容,但在具体选型之前仍需综合评估业务特性决定最适合自己的解决方案,毕竟有时候牺牲一点精确度换取更高的时效性也是合理的折衷办法[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值