服务端代码,包含远程客户端类、服务端类、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; } } }