C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能)

        本文章向大家介绍C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能),主要包括C# TCPclient 服务器保持长连接的一种办法(变相的心跳包功能)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace ALARMIP
{
    public partial class Form1 : Form
    {      
       //客户端定时向服务器发送查询指令
//服务器内置时钟计数,收到查询指令清零,计数超过则跳出循环,重新产生线程,线程内运行阻塞等待新的连接
//这样如果客户端连接一次就可以持续查询服务器设备,如果出现网络异常或者链接中断,只需客户端重新建立连接
//这个实例的好处是避免采用异步方法造成的非阻塞连接(要求客户端也用非阻塞方式,很多第三方工具无法调试)
       
        byte[] pollingCommand = new byte[12] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x30 };
        // 客户端轮询指令,事务处理标识2字节,协议标识2字节,长度标识2字节,单元标识00,功能标识0A,起始处理器号,总处理器数
        //00 00 00 00 00 06 01 04 00 01 00 30 
 
        byte[] infoTCP = new byte[57] {0x00, 0x00, 0x00, 0x00, 0x00, 0x33,0x61, 0x04, 0x30,           
                                                                               
                                    0x00,0x00,0x00,                  //0
                                    0x00,0x00,0x00 ,                     //pm1
                                    0x00,0x00,0x00,                     //2
                                    0x00,0x00,0x00,                     //3
                                    0x00,0x00,0x00,                        //4
                                    0x00,0x00,0x00,                     //5
                                    0x00,0x00,0x00,                    //6
                                    0x00,0x00,0x00,                     //7
                                    0x00,0x00,0x00,                    //8
                                    0x00,0x00,0x00,                     //9
                                    0x00,0x00,0x00,                    //10
                                    0x00,0x00,0x00,                   //11
                                    0x00,0x00,0x00,                //12
                                    0x00,0x00,0x00,                //13
                                    0x00,0x00,0x00,               //14
                                    0x00,0x00,0x00                 //15
        };

        bool isAlarmIPReady = true  ;                       //服务器数据汇总是否完成,由时钟确定,默认500ms,接收到轮询指令且该值为1时答复,否则不做应答;应答后修改为0
        bool isPolling=true ;     //是否收到轮询指令
        private bool isListening; //控制连接传输循环
        private TcpListener listener;
        private Thread aThread;
        private bool isTcpConnected; //存在连接线程的标志,控制线程
        private int pollingLost;   //无客户端查询次数,网络断开也可用,定时器自动加1,通讯成功则清零
  

     
        public Form1()
        {
            InitializeComponent();
        }


        private void Form1_Load(object sender, EventArgs e)
        { 
            timer1.Start();
            Thread.Sleep(500);
            listener = new TcpListener(IPAddress.Any, 502);   //新建socket,允许局域网所有终端访问
            listener.Start();
            aThread = new Thread(Queue1Thread);   //连接线程
            isTcpConnected = true;  //连接状态标志
            
            aThread.Start();
        }
 
            
        private void timer1_Tick(object sender, EventArgs e)
        {
            isAlarmIPReady = true;  //每500ms标志一次
         
            if(!isListening)
            {
                if (!isTcpConnected)
                {
                    aThread = new Thread(Queue1Thread);
                    isTcpConnected = true; //立即标识启动连接,避免开多个线程
                    
                    aThread.Start();
                }
            }
            else
            {
                if(++pollingLost>10)
                {
                    pollingLost = 10;// 简易的心跳包,根据
                    isListening = false; //让TCP线程跳出循环
                }
            }
        }


        private void Queue1Thread(object state)
        {
            TcpClient client = new TcpClient();
            client = listener.AcceptTcpClient();  //阻塞,等待新的连接
            isListening = true; //该值应该在子线程赋值,如果在主线程,有可能是上一个线程的值false,直接跳出下面的循环而断开连接
            pollingLost = 0; //同上
            while (isListening)
            {
                if (client != null)
                {
                    NetworkStream stream = client.GetStream();  //这个对象有系统回收
                    byte[] buffer = new byte[256];
                    int ki = client.ReceiveBufferSize;
                    this.Invoke((EventHandler)(delegate
                    {
                        //this.Text = ki.ToString()+DateTime.Now .ToLongTimeString();
                    }));

                    stream.Read(buffer, 0, 256);
                    if (ki > 11)
                    {
                        isPolling = true;
                        for (int i = 2; i < 11; i++)
                        {
                            if (pollingCommand[i] != buffer[i])
                            {
                                isPolling = false; //对客户端请求验证,避免错码
                            }
                        }
                        if (isAlarmIPReady & isPolling)
                        {
                            isAlarmIPReady = false;
                            pollingLost = 0;  //连接失败数清零
                            infoTCP[0] = buffer[0];
                            infoTCP[1] = buffer[1];
                            stream.Write(infoTCP, 0, 57);
                            // MessageBox.Show(infoTCP [5].ToString());
                        }
                       
                    }
                }
            }
            client.Close();  //加此处理,则5秒超时后,客户端不重连而发送查询后连接将关闭;如果不做处理,系统将自动回收,客户端不重连发送查询后连接显示保持但是实际上已经断开了连接
            isTcpConnected = false; 
        }  
    }
}

http://www.manongjc.com/article/37725.html

当然可以!下面是一个简单的示例,展示如何使用C#TcpClient类创建一个基本的服务器和客户端。 首先是服务器端的代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; public class Server { public static void Main() { IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); // 设置服务器IP地址 int port = 8888; // 设置服务器端口号 TcpListener listener = new TcpListener(ipAddress, port); listener.Start(); Console.WriteLine("服务器启动,等待客户端连接..."); TcpClient client = listener.AcceptTcpClient(); // 等待客户端连接 Console.WriteLine("客户端连接成功!"); NetworkStream stream = client.GetStream(); byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0) { string data = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("接收到消息: " + data); // 处理接收到的消息,这里简单地将消息转为大写后返回 string response = data.ToUpper(); byte[] responseData = Encoding.ASCII.GetBytes(response); stream.Write(responseData, 0, responseData.Length); Console.WriteLine("发送响应: " + response); } client.Close(); listener.Stop(); } } ``` 接下来是客户端的代码: ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; public class Client { public static void Main() { string serverIP = "127.0.0.1"; // 设置服务器IP地址 int serverPort = 8888; // 设置服务器端口号 TcpClient client = new TcpClient(serverIP, serverPort); Console.WriteLine("与服务器连接成功!"); NetworkStream stream = client.GetStream(); while (true) { Console.Write("请输入要发送的消息: "); string message = Console.ReadLine(); byte[] data = Encoding.ASCII.GetBytes(message); stream.Write(data, 0, data.Length); byte[] buffer = new byte[1024]; int bytesRead = stream.Read(buffer, 0, buffer.Length); string response = Encoding.ASCII.GetString(buffer, 0, bytesRead); Console.WriteLine("接收到响应: " + response); } client.Close(); } } ``` 这是一个简单的示例,服务器端接收客户端发送的消息并将其转换为大写后返回给客户端。你可以根据自己的需求进行进一步的扩展和修改。记得在运行代码之前,先启动服务器端再启动客户端。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值