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;
                }
            }
        }

 

转载于:https://www.cnblogs.com/KQNLL/p/5234160.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值