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);
    })
    );
}
相关推荐
Chen—LSN7 小时前
C语言——文件操作(2)
c语言·开发语言·c++·经验分享·笔记·算法·c#
淡海水10 小时前
00-Unity和C#的GC剖析与对比-全篇导览
unity·c#·游戏引擎·gc
fogota11 小时前
C# `string.Join` 处理 `List<int>`
windows·c#
Behavior13 小时前
Unity 手游动态更换 App 图标 — Android 与 iOS 双端技术方案
c#·unity3d·游戏开发
周杰伦fans14 小时前
构建真正智能的CAD AI绘图代理
开发语言·人工智能·c#
UIU11417 小时前
递归算法与汉诺塔
c++·学习·算法·c#·递归
CSharp精选营1 天前
我用 ASP.NET Core 做了个水稻病虫害检查系统
c#·毕业设计·.net core·码农刚子
唐青枫1 天前
我用 C# 开发了一款电子发票自动整理工具
c#·.net
下页、再停留1 天前
【C#桌面客户端系列学习-2】在原来窗口基础上打开新窗口
c#·visual studio
Behavior1 天前
Unity 手游 iOS Deep Link 唤醒全流程:从 URL Scheme / Universal Links 到 C# 层参数投递
c#·unity3d·游戏开发