zoukankan      html  css  js  c++  java
  • C# TCP通信

    服务端代码,包含远程客户端类、服务端类、UI。
    //远程客户端类
    class RemoteClient { public TcpClient client{get; private set;} public BinaryReader br{get; private set;} public BinaryWriter bw{get; private set;} public string userName {get; set; } public RemoteClient(TcpClient client) { this.client = client; NetworkStream networkStream = client.GetStream(); br = new BinaryReader(networkStream); bw = new BinaryWriter(networkStream); this.userName = (client.Client.RemoteEndPoint as IPEndPoint).Address.ToString() + ":"+(client.Client.RemoteEndPoint as IPEndPoint).Port.ToString(); } public void Close() { br.Close(); bw.Close(); client.Close(); } }
        /// <summary>
        /// 服务器的类
        /// </summary>
        class _TcpServer
        {
            //远程客户端对象集合
            List<RemoteClient> remoteClientList = new List<RemoteClient>();     
            private TcpListener tcpServer;
    
            public _TcpServer(string localIP,int port)
            {
                /// <summary>使用的本机IP地址</summary>
                IPAddress localAddress = IPAddress.Parse(localIP); 
                tcpServer = new TcpListener(localAddress, port);
                tcpServer.Start();
                //创建一个线程监听客户端连接请求
                Thread myThread = new Thread(ListenClientConnect);
                myThread.Start();
            }
    
            /// <summary>接收客户端连接</summary>
            private void ListenClientConnect()
            {
                TcpClient newClient = null;
                while (true)
                {
                    try
                    {
                        newClient = tcpServer.AcceptTcpClient();
                    }
                    catch
                    {
                        //当单击“停止监听”或者退出此窗体时AcceptTcpClient()会产生异常
                        //因此可以利用此异常退出循环
                        break;
                    }
                    //每接受一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息
                    RemoteClient user = new RemoteClient(newClient);
                    Thread threadReceive = new Thread(ReceiveData);
                    threadReceive.Start(user);
                    remoteClientList.Add(user);
                    ClassVar.WriteLogCommon(Environment.NewLine + "有远程主机连接到本机,远程主机信息:"+user.userName);
                }
            }       
    
            /// <summary>
            /// 处理接收的客户端数据
            /// </summary>
            /// <param name="userState">客户端信息</param>
            private void ReceiveData(object userState)
            {
                RemoteClient user = userState as RemoteClient;
                TcpClient client = user.client;
                while (true)
                {
                    byte[] BytesLenth = null;
                    byte[] BytesContent = null;
                    try
                    {
                        if (user == null || user.br == null || user.client.Connected == false)
                        {
                            break;
                        }
                        BytesLenth = user.br.ReadBytes(2);
                        int lenth = BitConverter.ToInt16(BytesLenth, 0);
                        BytesContent = user.br.ReadBytes(lenth - 2);
                        string conContent = Encoding.Default.GetString(BytesContent);                 
                        //如果收到是心跳信息
                        if (conContent == "0000")
                        {
                            lock (ClassVar.frmMain.objTimeSpan)
                            {
                                ClassVar.frmMain.timeSpan = 0;                         
                            }
                            ClassVar.WriteLogCommonXT(Environment.NewLine + "收到心跳消息");
                        }
                        //如果是警情信息则加入到消息队列
                        else
                        {
                            lock (ClassVar.frmMain.lockQue)
                            {
                                ClassVar.frmMain.queue119Xml.Enqueue(conContent);                            
                            }
                            ClassVar.WriteLogCommon(Environment.NewLine + "收到数据:" + conContent);
                        }
                    }
                    catch (Exception ex)
                    {
                        RemoveUser(user);
                        ClassVar.WriteErrorLog("接收消息异常:" + Environment.NewLine + "ReceiveData" + ex.ToString());
                    }
                }
            }
    
            /// <summary>移除用户</summary>
            /// <param name="user">指定要删除的用户</param>
            private void RemoveUser(RemoteClient remoteClient)
            {
                remoteClientList.Remove(remoteClient);
                remoteClient.Close();          
            }
        }

    服务端UI

            //服务器给本机发送的心跳计时锁对象
            public object lockQue = new object();
    //接收的客户端消息列表
    public Queue<string> queue119Xml = new Queue<string>();
            private void IniServer()
            {
                //启动监听119服务器,用于接收发送119发送的消息
                _TcpServer _119TcpListen = new _TcpServer(ClassVar.localIPAddr, 11118);
                Thread threadRead119 = new Thread(new ThreadStart(Read119QueThread));
                threadRead119.IsBackground = true;
                threadRead119.Start();
            }
           //读取消息队列
            private void Read119QueThread()
            {
                while (true)
                {
                    try
                    {
                        if (queue119Xml.Count > 0)
                        {
                            lock (lockQue)
                            {
                                string xml = queue119Xml.Dequeue();
                                F119ToLocal(xml);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        ClassVar.WriteErrorLog("方法Read119QueThread出错,详细信息:" + ex.ToString());
                    }
                    Thread.Sleep(5);
                }
            } 
        /// <summary>
        /// 客户端类
        /// </summary>
        class _Client
        {
            // tcp通信对象
            private TcpClient tcpClient;
            // tcp通信中读取数据的对象
            private BinaryReader br;
            // tcp通信中写数据的对象
            private BinaryWriter bw;
            // 通信的远程服务器ip
            private string IP;
            // 通信的远程服务器端口
            private int port;
    
            /// <summary>
            /// 构造函数
            /// </summary>
            /// <param name="ip">服务器IP</param>
            /// <param name="port">服务器开放的通信端口号</param>
            public _Client(string ip,int port)
            {
                this.IP = ip;
                this.port = port;
            }
    
            /// <summary>
            /// 连接服务器
            /// </summary>
            public void Connect()
            {
                try
                {
                    tcpClient = new TcpClient(IP, port);
                    //获取网络流
                    NetworkStream networkStream = tcpClient.GetStream();
                    //将网络流作为二进制读写对象
                    br = new BinaryReader(networkStream);
                    bw = new BinaryWriter(networkStream);
                }
                catch (Exception ex)
                {
                    ClassVar.WriteErrorLog("连接服务器出错:" + Environment.NewLine + "Connect" + ex.ToString());
                }
                //后台心跳消息线程
                Thread threadHeart = new Thread(new ThreadStart(SendHeart));
                threadHeart.IsBackground = true;
                threadHeart.Start();
            }
    
            /// <summary>
            /// 重连
            /// </summary>
            public void Reconnect()
            {
                try
                {
                    if (tcpClient!=null)
                    {
                        tcpClient.Close();
                    }              
                    tcpClient = new TcpClient(IP, port);
                    //获取网络流
                    NetworkStream networkStream = tcpClient.GetStream();
                    //将网络流作为二进制读写对象
                    br = new BinaryReader(networkStream);
                    bw = new BinaryWriter(networkStream);
                }
                catch(Exception ex)
                {
                    ClassVar.WriteErrorLog("重连服务器出错:" + Environment.NewLine + "Reconnect" + ex.ToString());
                }
            }
          
            /// <summary>
            /// 给服务器心跳,10秒一次
            /// </summary>
            private void SendHeart()
            {
                while (true)
                {
                    Thread.Sleep(10000);
                    SendMsg("0000");
                }
            }
            
            /// <summary>
            /// 发送消息到服务器的方法,带发送长度
            /// </summary>
            /// <param name="msg">消息内容</param>
            public void SendMsg(string msgs)
            {
                try
                {
                    byte[] msg = Encoding.UTF8.GetBytes(msgs);
                    int length = msg.Length;
                    short lengthall = (short)(length + 2);
                    byte[] lengthByte = System.BitConverter.GetBytes(lengthall);
                    byte[] all = lengthByte.Concat(msg).ToArray();
                    //然后将字节数组写入网络流
                    if (bw != null && tcpClient.Connected==true)
                    {
                            bw.Write(all);
                            bw.Flush();
                            if (msgs == "0000")//心跳写单独的文件
                            {
                                ClassVar.WriteLogCommonXT(Environment.NewLine + "成功发送数据:" + msgs);
                            }
                            else
                            {
                                ClassVar.WriteLogCommon(Environment.NewLine + "成功发送数据:" + msgs);
                            }
                    }
                    else
                    {
                        this.Reconnect();
                    }
                }
                catch (Exception ex)
                {
                    ClassVar.WriteErrorLog("发送消息到服务器出错:" + Environment.NewLine + "SendMsg" + ex.ToString());
                }
            }
        }

     客户端代码

            // 与服务器通信的类
            _Client client ;
            //服务器给本机发送的心跳计时锁对象
            public object objTimeSpan = new object();
            //服务器给本机发送的心跳计时
            public int timeSpan = 0;
     private void IniClient()
            {
                client = new _Client(_119ServerIP, _119ServerPort);
                //连接服务器
                client.Connect();
                //与服务器重连判断线程
                Thread threadChenck = new Thread(new ThreadStart(CheckHeart));
                threadChenck.IsBackground = true;
                threadChenck.Start();
                client.SendMsg("测试发送信息到服务端");
            }
            // 重连判断
            private void CheckHeart()
            {
                while (true)
                {
                    Thread.Sleep(3000);
                    lock (objTimeSpan)
                    {
                        timeSpan = timeSpan + 2;
                    }
                    if (timeSpan >= maxTime)
                    {
                        client.Reconnect();
                        timeSpan = 0;
                    }
                }
            }
  • 相关阅读:
    mysql数据库基础知识
    js与jquery操作
    4月16日的错题整理
    智还王项目中出现的问题和使用的一些方法
    dom操作
    二维数组的定义与用法
    数组内容
    网页布局时遇到的问题
    css初接触
    表单
  • 原文地址:https://www.cnblogs.com/KQNLL/p/5234160.html
Copyright © 2011-2022 走看看