首页 > 编程语言 >C#-TCP协议通讯(一)-TCPClientHelper

C#-TCP协议通讯(一)-TCPClientHelper

时间:2023-03-16 22:12:14浏览次数:31  
标签:TCPClientHelper C# ResultData TCP 线程 btnOpenCloseThread new 监听

一、TCPClinet知识点

1、创建TCPClient客户端发送消息示例:

        /// <summary>
        /// 发送消息-未做粘包和拆包处理
        /// </summary>
        /// <param name="msg">数据流</param>
        /// <returns></returns>
        public ResultData_TCP SendMsg_Nohandle(string msg)
        {
            ResultData_TCP resultData_TCP = new ResultData_TCP();

            try
            {
                // TcpClient _tcpClient = new TcpClient(hostname, port);  // 先开启连接
                
                byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);

                NetworkStream stream = _tcpClient.GetStream();  // 获取当前数据流
                stream.Write(data, 0, data.Length);  // 写入
                stream.Flush();
                stream.Close();  // 关闭流

                resultData_TCP = new ResultData_TCP()
                {
                    ResultCode = 1,
                    ResultMsg = "发送成功!"
                };
            }
            catch (ArgumentNullException e)
            {
                Console.WriteLine("ArgumentNullException: {0}", e);
                resultData_TCP = new ResultData_TCP()
                {
                    ResultCode = -1,
                    ResultMsg = string.Concat("参数无效;错误内容: ", e.HResult, ",", e.Message)
                };
            }  // 参数无效(当将 null 引用传递到不接受其作为有效参数的方法时引发的异常。)
            catch (SocketException e)
            {
                Console.WriteLine("SocketException: {0}", e);
                resultData_TCP = new ResultData_TCP()
                {
                    ResultCode = -1,
                    ResultMsg = string.Concat("网络异常,套接字错误;错误内容: ", e.HResult, ",", e.Message)
                };
            }  // 套接字错误(发生套接字错误时引发的异常。)
            catch (Exception ex)
            {
                resultData_TCP = new ResultData_TCP()
                {
                    ResultCode = -1,
                    ResultMsg = string.Concat("发生错误;错误内容: ", ex.HResult, ",", ex.Message),
                };
            }  // 其他错误信息
            return resultData_TCP;
        }

2、创建TcpListener监听TCPClient(线程-Net Framework):

            try
            {
                if (btnOpenCloseThread.Text == "开启监听-控制线程")  // 开启监听
                {
                    // 检查地址
                    if (!CheckServerUrl())
                    {
                        return;
                    }
                    IPHostEntry ipInfo = Dns.Resolve("127.0.0.1");  // 主机信息
                    IPAddress[] ipList = ipInfo.AddressList;        // IP数组
                    IPAddress localAddr = ipList[0];                // IP

                    int port = int.Parse(txtPort.Text);
                    _listenter = _TCPHelper.TcpListener_Start(localAddr, port);
                    _listenter.Start(); // 开始监听

                    thListener = new Thread(new ThreadStart(Run)); //定义线程进行监听
                    thListener.IsBackground = true;
                    thListener.Start(); //线程启动

                    btnOpenCloseThread.Text = "关闭监听-控制线程";
                    btnOpenCloseThread.BackColor = Color.FromArgb(128, 255, 128);
                }
                else  // 关闭监听
                {
                    if (thListener != null)
                    {
                        //thListener.Interrupt();
                         _listenter.Stop();
                    }
                    
                    btnOpenCloseThread.Text = "开启监听-控制线程";
                    btnOpenCloseThread.BackColor = Color.FromArgb(255, 128, 128);
                }
            }
            catch (Exception ex)
            {
                btnOpenCloseThread.Text = "开启监听-控制线程";
                btnOpenCloseThread.BackColor = Color.FromArgb(255, 128, 128);

                ShowLog($"开启/关闭监听失败,错误信息: {ex.Message}");
            }

3、创建TcpListener监听TCPClient(线程池-Net 5):

 

4、创建TcpListener监听TCPClient(线程委托,线程外修改循环线程中的变量-Net 5):

 

二、处理TCP粘包与拆包

1、固定消息长度 + 缓存

 

2、消息前后加特殊字符标记边界 + 缓存

string dd=$"{边界标识}{数据流}{边界标识}";

3、定义消息结构体,结构体中定义一个字段存储信息长度 + 缓存

string dd="Header{开始标记+一个内容的长度}+Body{数据流}";

 

注:Netty框架提供了上述解决方法。

标签:TCPClientHelper,C#,ResultData,TCP,线程,btnOpenCloseThread,new,监听
From: https://www.cnblogs.com/qq2806933146xiaobai/p/17224366.html

相关文章

  • 用CPU来加速你的Linux命令
    我们都知道grep,bzip2,wc,awk,sed等等,都是单线程的,只能使用一个CPU内核。那么如何才能使用这些内核?要想让Linux命令使用所有的CPU内核,我们需要用到GNUParallel命令,......
  • MCU芯片设计流程
    MCU设计流程1.产品开发整体流程IntegratedProductDevelopment(IPD)TR-TechniqueReview-技术评审xDCP-管理层决定是否开发这里的验证指的是小批量的试制TR1技术......
  • Docker CLI docker commit 常用命令
    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。Doc......
  • LeetCode 18. 四数之和
    classSolution{public:vector<vector<int>>fourSum(vector<int>&nums,inttarget){vector<vector<int>>ans;longlongtmp=target;......
  • Curator版本依赖问题
    在项目中引入Curator时,会出现启动报错问题以及打包失败的问题,经过不断的排查,在排查尝试的过程中出现了如下问题:springboot项目启动失败;报错log4j和logbook依赖冲突打包......
  • LeetCode1024 -- 二分
    1.题目描述查找满足劳累天数严格大于不劳累天数的最大子区间2.思路对于区间问题,很容易先想到前缀和帮助我们优化。我们可以设,劳累=\(1\),不劳累=\(-1\),那么,就是求......
  • Object.definePropoty()方法详解
    Object.definePropoty()方法有三个参数第一个参数为:需要进行代理的目标对象,target第二个参数为:需要代理的这个对象中对应的"键"名,key第三个参数为:{}一个配置项......
  • cb
    点击查看代码<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>Code</title><style>body{margin:0;......
  • ChatGPT对于滤除微多普勒运动目标的解决方案
    上一篇体验了一把GPT的真香定律,赶紧又问了一些同事问的如何滤除微多普勒目标的问题。感觉还可以,后面可以试试看,具体大家可以一起看看这个回答,还是有一些可以采纳的意见......
  • 血泪的线上bug,有关Object.fromEntries
    因为这个线上bug引发的反思:1,兼容性测试的重要性2,代码review的重要性3,技术敏感的重要性还有很多……因为出现线上bug,这个链路上每个人都有责任和需要学习的地方,而作为......