C# 56. Tcp Server

1. TCP Server类
c 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Xxxxx
{
    public class TcpServer
    {
        private TcpListener listener;
        private bool isRunning = false;
        private dataProcessdelegate dataProcessFunc;


        public bool StartServer(string ip, int port, dataProcessdelegate dataProcessFunc1)
        {
            if(isRunning == false)
            {
                dataProcessFunc = dataProcessFunc1;
                IPAddress ipAddress = IPAddress.Parse(ip);
                listener = new TcpListener(ipAddress, port);
                Start();
            }
            else
            {
                Stop();
            }
            return isRunning;
        }

        public void Start()
        {
            isRunning = true;
            listener.Start();
            Console.WriteLine($"Server started and listening on port {listener.LocalEndpoint}");

            Task.Run(() => AcceptClientsAsync());
        }

        public void Stop()
        {
            isRunning = false;
            listener.Stop();
            Console.WriteLine("Server stopped.");
        }

        private async Task AcceptClientsAsync()
        {
            while (isRunning)
            {
                try
                {
                    TcpClient client = await listener.AcceptTcpClientAsync();       //#1
                    Console.WriteLine("Client connected.");
                    HandleClientAsync(client);      //#2,前面没有awiat则不会停在HandleClientAsync而是跳到#1。加了awiat则等待HandleClientAsync执行完成
                }
                catch (ObjectDisposedException) when (!isRunning)
                {
                    // Server is stopping, ignore this exception
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error accepting client: {ex.Message}");
                }
            }
        }

        private async Task HandleClientAsync(TcpClient client)
        {
            NetworkStream stream = client.GetStream();
            byte[] buffer = new byte[2048];
            int bytesRead;

            bool isRunningLocally = true; // 局部标志,用于控制循环

            try
            {
                while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0 && isRunningLocally)
                {
                    //string message = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    string message = System.Text.Encoding.Default.GetString(buffer, 0, bytesRead);
                    Console.WriteLine($"Received from client: {message}");

                    dataProcessFunc(buffer, bytesRead);

                    // 检查服务器是否仍在运行
                    if (!isRunning)
                    {
                        isRunningLocally = false; // 设置标志以跳出循环
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error handling client: {ex.Message}");
            }
            finally
            {
                client.Close();
                Console.WriteLine("Client disconnected.");
            }
        }
    }
}
2. 主类
c 复制代码
//定义一个数据处理的委托
dataProcessdelegate dataProcessFunc;

TcpServer tcpServer = new TcpServer();
private void buttonOpenServer_Click(object sender, EventArgs e)
{
    if (serialPort1.IsOpen)
    {
        MessageBox.Show("请先关闭串口!");
        return;
    }
    bool flag;
    dataProcessFunc = new dataProcessdelegate(CmdParseInvoke);    
    flag = tcpServer.StartServer(textBoxIP.Text.Trim(), Convert.ToInt32(this.textBoxPort.Text.Trim()),  dataProcessFunc);
    if (flag == true)   //已连接
    {
        CommType = CommTypeEnum.TcpType;
        buttonOpenServer.Text = "关闭服务";
        buttonOpenServer.BackColor = Color.LightCoral;
    }
    else
    {
        CommType = CommTypeEnum.UnSelectType;
        buttonOpenServer.Text = "打开服务";
        buttonOpenServer.BackColor = Color.LimeGreen;
    }
}

private void CmdParseInvoke(byte[] buf, int length)
{
    Invoke((EventHandler)(delegate
    {
        CmdParse(buf, length);
    })
    );
}
相关推荐
阿蒙Amon9 天前
《C#图解教程 第5版》深度推荐
开发语言·c#
暖馒9 天前
C#委托与事件的区别
开发语言·c#
JosieBook9 天前
【C#】C#异步编程:异步延时 vs 阻塞延时深度对比
c#·多线程·异步·阻塞
甄天9 天前
WPF中MVVM和MVVMLight模式
c#·wpf·visual studio
冰茶_9 天前
ASP.NET Core API文档与测试实战指南
后端·学习·http·ui·c#·asp.net
_oP_i9 天前
实现 “WebView2 获取word选中内容
开发语言·c#·word
Kookoos9 天前
ABP vNext + Azure Application Insights:APM 监控与性能诊断最佳实践
后端·c#·.net·abp vnext
专注VB编程开发20年9 天前
asp.net core Razor动态语言编程代替asp.net .aspx更高级吗?
开发语言·后端·c#·asp.net·.net
安木夕10 天前
C#.Net筑基-优雅LINQ的查询艺术
c#·.net
软泡芙10 天前
【C#】托管和非托管
java·c#