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);
    })
    );
}
相关推荐
Panda__Panda5 小时前
docker项目打包演示项目(数字排序服务)
运维·javascript·python·docker·容器·c#
weixin_456904276 小时前
基于.NET Framework 4.0的串口通信
开发语言·c#·.net
Tiger_shl7 小时前
C# 预处理指令 (# 指令) 详解
开发语言·c#
sali-tec8 小时前
C# 基于halcon的视觉工作流-章45-网格面划痕
开发语言·算法·计算机视觉·c#
云草桑12 小时前
C#入坑JAVA 使用XXLJob
java·开发语言·c#
玉夏12 小时前
【每日算法C#】爬楼梯问题 LeetCode
算法·leetcode·c#
云草桑18 小时前
.net AI MCP 入门 适用于模型上下文协议的 C# SDK 简介(MCP)
ai·c#·.net·mcp
工程师00720 小时前
C#中堆和栈的概念
c#·堆和栈
weixin_3077791321 小时前
C#实现MySQL→Clickhouse建表语句转换工具
开发语言·数据库·算法·c#·自动化
CsharpDev-奶豆哥1 天前
ASP.NET中for和foreach使用指南
windows·microsoft·c#·asp.net·.net