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);
    })
    );
}
相关推荐
开开心心就好3 小时前
高效Excel合并拆分软件
开发语言·javascript·c#·ocr·排序算法·excel·最小二乘法
一名用户4 小时前
unity实现自定义粒子系统
c#·unity3d·游戏开发
钢铁男儿6 小时前
C# 类和继承(扩展方法)
java·servlet·c#
爱炸薯条的小朋友6 小时前
C#由于获取WPF窗口名称造成的异常报错问题
windows·c#·wpf
Rose 使者8 小时前
全球IP归属地查询接口如何用C#进行调用?
c#·api·ip地址
~plus~10 小时前
Harmony核心:动态方法修补与.NET游戏Mod开发
开发语言·jvm·经验分享·后端·程序人生·c#
htj1010 小时前
C# 使用正则表达式
正则表达式·c#
~plus~10 小时前
WPF八大法则:告别模态窗口卡顿
开发语言·经验分享·后端·程序人生·c#
就是有点傻11 小时前
使用WPF的Microsoft.Xaml.Behaviors.Wpf中通用 UI 元素事件
c#
qq_2979080111 小时前
C#报价系统陈列展示成本核算系统项目管理系统纸品非纸品报价软件
sqlserver·c#·.net·开源软件