// //tc:正要发给数据的目地客户端 tcSource:提交数据的源头客户端 // //此发送程序用于向PC发送数据,用ep来定位目的客户端 // //一旦发送成功,则将该客户端的Source列中增加sourceEp // public void TCPServerSend(IPEndPoint Txep, FrameStruc bufFrame, IPEndPoint sourceEp) // { // try // { // if (Txep == null) // return; // if (sourceEp == null) // return; // if (bufFrame == null) // return; // TcpClient tc = null; // TCPLlientList tcc=new TCPLlientList(); // lock (lockTCPLink) // { // for (int y = TCPClientArray.Count - 1; y >= 0; y--)//找出要发数据的客户端,最后一个有效的会被找到,实际上应该只有一个 // { // if (TCPClientArray[y].thisClient.Client.RemoteEndPoint .Equals( Txep)==true) // { // tcc = TCPClientArray[y]; // tc = TCPClientArray[y].thisClient; // } // } // } // if (tc == null)//指定的目的端点没有找到,退出 // { // return; // } // NetworkStream sendStream = tc.GetStream(); // Byte[] sendBytes = new byte[bufFrame.datalen + 11]; // sendBytes[0] = bufFrame.head1; // sendBytes[1] = bufFrame.head2; // sendBytes[2] = bufFrame.idl; // sendBytes[3] = bufFrame.idh; // sendBytes[4] = bufFrame.addr1; // sendBytes[5] = bufFrame.addr2; // sendBytes[6] = bufFrame.cmd; // sendBytes[7] = (byte)(bufFrame.datalen); // sendBytes[8] = (byte)(bufFrame.datalen >> 8); // int i = 0; // for (i = 0; i < bufFrame.datalen; i++) // { // sendBytes[9 + i] = bufFrame.databuf[i]; // } // sendBytes[9 + i] = bufFrame.check1; // sendBytes[10 + i] = bufFrame.check2; // sendStream.Write(sendBytes, 0, sendBytes.Length); // sendStream.Flush(); // if (sourceEp.Equals(MyIPEndPoint)==true) // { // LogArrived_Event(-1, (IPEndPoint)tcc.thisClient.Client.RemoteEndPoint, tcc.ID, "服务器向PC发送完整帧", tcc.Area, tcc.WellOrUser, bufFrame); // } // else // { // LogArrived_Event(-1, (IPEndPoint)tcc.thisClient.Client.RemoteEndPoint, tcc.ID, "DTU向PC发送完整帧", tcc.Area, tcc.WellOrUser, bufFrame); // } // } // catch(Exception ex) // { //#if DBG // MessageBox.Show("TCPServer:发送数据子程序1" + System.Environment.NewLine + ex.ToString()); //#endif // } // } //id:正要发给数据的目地客户端 tcSource:提交数据的源头客户端 //此发送子程序用于PC向DTU,用DTU的ID来定位目的客户端 //一旦发送成功,则将该客户端的Source列中增加sourceEp public void TCPServerSend(FrameStruc bufFrame) { if (bufFrame == null) { return; } try { ushort idt = (ushort)(bufFrame.tidh * 256 + bufFrame.tidl); ushort ids = (ushort)(bufFrame.sidh * 256 + bufFrame.sidl); if (idt < 1)//id<1的客户端编号为非法 { LogArrived_Event(0, MyIPEndPoint, idt, string.Format("目标ID({0})非法,发送帧失败。", idt), "", "", bufFrame); return; } //发送前先查询该目的客户端的ID是否在在线列表里,并找出对应的EndPoint TCPLlientList tcc = new TCPLlientList(); lock (lockTCPLink) { for (int y = TCPClientArray.Count - 1; y >= 0; y--)//找出要发数据的客户端,最前面一个有效的会被找到,实际上应该只有一个 { if (TCPClientArray[y].ID == idt) { tcc = TCPClientArray[y]; } } } if (tcc.thisClient == null) { LogArrived_Event(0, MyIPEndPoint, idt, string.Format("目标ID({0})不在线,发送帧失败。", idt), "", "", bufFrame); return; } NetworkStream sendStream = tcc.thisClient.GetStream(); Byte[] sendBytes = new byte[bufFrame.datalen + 13]; sendBytes[0] = bufFrame.head1; sendBytes[1] = bufFrame.head2; sendBytes[2] = bufFrame.tidl; sendBytes[3] = bufFrame.tidh; sendBytes[4] = bufFrame.sidl; sendBytes[5] = bufFrame.sidh; sendBytes[6] = bufFrame.addr1; sendBytes[7] = bufFrame.addr2; sendBytes[8] = bufFrame.cmd; sendBytes[9] = (byte)(bufFrame.datalen); sendBytes[10] = (byte)(bufFrame.datalen >> 8); int i = 0; for (i = 0; i < bufFrame.datalen; i++) { sendBytes[11 + i] = bufFrame.databuf[i]; } sendBytes[11 + i] = bufFrame.check1; sendBytes[12 + i] = bufFrame.check2; sendStream.Write(sendBytes, 0, sendBytes.Length); sendStream.Flush(); LogArrived_Event(-1, (IPEndPoint)tcc.thisClient.Client.RemoteEndPoint, tcc.ID, string.Format("发送帧(目标ID={0} 源ID={1})", idt, ids), tcc.Area, tcc.WellOrUser, bufFrame); } catch (Exception ex) { #if DBG MessageBox.Show("TCPServer:发送数据" + System.Environment.NewLine + ex.ToString()); #endif } }
private void startListen() { try { MyTCPListener.Start(); while (m_bListening) //死循环监听是否有新的客户端上线 { TcpClient newTcpClient = MyTCPListener.AcceptTcpClient(); //在这儿死等,直到有新的客户端连接上 #region 如果客户端在线列表中已存在这个端点,则把先前的那个客户端关闭并删掉,并加入现在这个客户端 int n = 0; lock (lockTCPLink) { for (int j = TCPClientArray.Count - 1; j >= 0; j--) { if (TCPClientArray[j].thisClient.Client.RemoteEndPoint.Equals(newTcpClient.Client.RemoteEndPoint) == true) { n++; TCPClientArray[j].thisClient.Close(); //客户端立即关闭 TCPClientArray.RemoveAt(j); //立即删除这一项 } } } #endregion #region 客户端列表增加一行 TCPLlientList tll = new TCPLlientList();//客户端刚上线 tll.thisClient = newTcpClient; tll.LoginTime = DateTime.Now; tll.lastTime = tll.LoginTime; lock (lockTCPLink) { TCPClientArray.Add(tll); //客户端列表中增加一项 } TCPClientLink_Event(true, lockTCPLink, TCPClientArray); //通知主界面增加一个新的客户端 #endregion if (n == 0) { LogArrived_Event(0, (IPEndPoint)newTcpClient.Client.RemoteEndPoint, 0, "新客户端上线"); } else { LogArrived_Event(0, (IPEndPoint)newTcpClient.Client.RemoteEndPoint, 0, "客户端上线,覆盖相同端点。"); } //这二行必须放在上面增加一行LOG的后面,否则接收数据线程里很快就把这个客户端关闭了,则上面增加LOG的语句可能执行出错,因为对象不存在了 clientBeginThread = new Thread(new ParameterizedThreadStart(AcceptMsg)); clientBeginThread.Start(newTcpClient);//为刚才新增加的客户端开一个独立线程进行监听 } } catch (Exception ex) { #if DBG MessageBox.Show("TCPServer:客户端监听线程" + System.Environment.NewLine + ex.ToString()); #endif } finally { if (MyTCPListener != null) { MyTCPListener.Stop(); } } }