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);
    })
    );
}
相关推荐
Humbunklung12 小时前
C# WPF 实现读取文件夹中的PDF并显示其页数
pdf·c#·wpf·npoi·gemini·itext
时光追逐者13 小时前
C#/.NET/.NET Core技术前沿周刊 | 第 48 期(2025年7.21-7.27)
c#·.net·.netcore·.net core
蓝点lilac13 小时前
C# 调用邮箱应用发送带附件的邮件
c#·.net
工程师00714 小时前
C#多线程,同步与异步详解
开发语言·c#·多线程·同步·异步编程
小乖兽技术16 小时前
在 .NET 中使用 Base64 时容易踩的坑总结
开发语言·c#·.net
小乖兽技术20 小时前
C#与C++交互开发系列(二十六):构建跨语言共享缓存,实现键值对读写与数据同步(实践方案)
c++·c#·交互
张人玉1 天前
c#Lambda 表达式与事件核心知识点整理
开发语言·python·c#
SkyrimCitadelValinor1 天前
c#中让图片显示清晰
开发语言·c#
爱吃香蕉的阿豪1 天前
SignalR 全解析:核心原理、适用场景与 Vue + .NET Core 实战
vue.js·microsoft·c#·.netcore·signalr
@蓝莓果粒茶1 天前
LeetCode第350题_两个数组的交集II
c++·python·学习·算法·leetcode·职场和发展·c#