小李程式™的专栏

有勇气来改变可以改变的事情,有度量接受不可改变的事情,有智慧来分辨两者的不同。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

C# UDP通讯类 多线程方式

Posted on 2005-08-22 17:09  尼斯湖李  阅读(7530)  评论(3编辑  收藏  举报
using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Collections;
namespace JsComm
{
/// <summary>
/// ----名称:UDP通讯类
/// ----建立:niefei
/// ----建立时间:2004-12-6
/// </summary>
/// <remarks>
/// ----使用说明与定义:
/// ----接到字符串 "NeedDownCards" 表示需要调用卡下载功能
/// </remarks>
public class UDPSocket
{
  private ArrayList m_computers;



  /// <summary>
  /// 发送命令文本常量
  /// </summary>
  private string m_sendText;



  /// <summary>
  /// 默认发送的字符串
  /// </summary>
  private const string m_sendStr="NeedDownCards";



  /// <summary>
  /// Udp对象
  /// </summary>
  private UdpClient m_Client;



  /// <summary>
  /// 本地通讯端口(默认8888)
  /// </summary>
  private  int m_LocalPort;



  /// <summary>
  /// 对方IP
  /// </summary>
  private string m_SendToIP;



  /// <summary>
  /// 远程通讯端口
  /// </summary>
  private  int m_RemotePort;



  /// <summary>
  /// 跟踪是否退出程序
  /// </summary>
  private  bool m_Done;



  /// <summary>
  /// 设置是否要发送
  /// </summary>
  private bool m_flag;



  /// <summary>
  /// 定义一个接受线程
  /// </summary>
  public Thread recvThread;



  /// <summary>
  /// 定义一个检测发送线程
  /// </summary>
  public Thread checkSendThread;



  /// <summary>
  /// 定义委托
  /// </summary>
  public delegate void  SOCKETDelegateArrive( string sReceived);



        /// <summary>
        /// 定义一个消息接收事件
        /// </summary>
  public event SOCKETDelegateArrive SOCKETEventArrive ;



  /// <summary>
  /// 下载标志
  /// </summary>
  public bool flag
  {
   set {this.m_flag=value;}
   get {return this.m_flag;}
  }



  /// <summary>
  /// 设置对方IP地址
  /// </summary>
  public string IP
  {
   set {m_SendToIP=value;}
   get {return m_SendToIP;}
  }



  /// <summary>
  /// 设置通讯端口
  /// </summary>
  public int LocalPort
  {
   set { m_LocalPort=value;}
   get { return m_LocalPort;}
  }



  /// <summary>
  /// 设置要发送的岗位对象
  /// </summary>
  public ArrayList computers
  {
   set { this.m_computers=value;}
   get { return this.m_computers;}
  }



  /// <summary>
  /// 断开接收 
  /// </summary>
  public bool Done
  {
   set { m_Done=value;}
   get { return m_Done;}
  }



  /// <summary>
  /// 构造函数设置各项默认值
  /// </summary>
  public UDPSocket()
  {
   m_sendText=string.Empty;
   m_computers=new ArrayList();
   m_Done=false;
   m_flag=false;
   m_LocalPort=8888;
   m_RemotePort=8888;
  }
   
  /// <summary>
  /// 析构函数
  /// </summary>
     ~UDPSocket(){Dispose();}



  /// <summary>
  /// 关闭对象
  /// </summary>
  public void Dispose() 
  {
            DisConnection();
   m_computers=null;
  }



  /// <summary>
  /// 初始化
  /// </summary>
  public void Init()
  {
   //初始化UDP对象
   try
   {
    m_Client=new UdpClient(m_LocalPort);



    SOCKETEventArrive("Initialize succeed by "+m_LocalPort.ToString() +" port");
   }
   catch 
   {
                SOCKETEventArrive("Initialize failed by "+m_LocalPort.ToString()+" port" );
   }
  }



  /// <summary>
  /// 关闭UDP对象
  /// </summary>
  public void DisConnection()
  {
   if (m_Client!=null)
   {
    this.Done =true;
    if (recvThread!=null)
    {
     this.recvThread.Abort();
    }
    if (checkSendThread!=null )
    {
                    this.checkSendThread.Abort();
    }
    m_Client.Close();
    m_Client=null;
    SOCKETEventArrive("UDP Object Closed");
    
   }
  }



  /// <summary>
  /// 向IP发送消息 自定义消息体
  /// </summary>
  public void send(string ip,string strBody)
  {
   this.IP =ip;
   this.m_sendText=strBody;
            sendCmd();
  }



  /// <summary>
  /// 发送向IP发送默认卡下载命令
  /// </summary>
  /// <param name="ip"></param>
  public void send(string ip)
  {
   this.IP=ip;
   this.m_sendText=m_sendStr;
            sendCmd();
  }
  
  /// <summary>
  /// 发送已知IP默认下载命令
  /// </summary>
  public void send()
  {
   this.m_sendText=m_sendStr;
            sendCmd();
  }



  /// <summary>
  /// 发送
  /// </summary>
  private void sendCmd()
  { 
   UdpClient udp=new UdpClient();
   try
   { 
    udp.Connect(this.m_SendToIP,m_RemotePort);
    // 连接后传送一个消息给ip主机
    Byte[] sendBytes = Encoding.ASCII.GetBytes(this.m_sendText); 
    udp.Send(sendBytes, sendBytes.Length);
    
    SOCKETEventArrive("Send:"+m_sendText+ " succeed");
   }  
   catch 
   {
    SOCKETEventArrive("Send:"+m_sendText +" failed");
   }
   finally
   { 
               udp.Close(); 
      udp=null;
   }
  }




  /// <summary>
  /// 侦听线程
  /// </summary>
  public void StartRecvThreadListener()
  {
   try
   {
    // 启动等待连接的线程
    recvThread = new Thread(new ThreadStart(Received));
    recvThread.Priority=ThreadPriority.Normal;
    recvThread.Start(); 
    SOCKETEventArrive("[Received]Thread Start....");
   }
   catch
   {
    SOCKETEventArrive("[Received]Thread Start failed!");
   }
  }




  /// <summary>
  /// 启动检测发送侦听线程
  /// </summary>
  public void StartCheckSendListenerThread()
  {
   try
   {
    checkSendThread=new Thread(new ThreadStart(ChekSendListener));
                checkSendThread.Priority=ThreadPriority.Normal;
    checkSendThread.Start();
    SOCKETEventArrive("[ChekSendListener]Thread Start...");
   }
   catch
   {
    SOCKETEventArrive("[ChekSendListener]Thread Start failed!");
   }
  }



  /// <summary>
  /// 检测发送标志对岗位对象数组发送下载命令
  /// </summary>
  private void ChekSendListener()
  {
   Thread.Sleep(1000);
   while (!m_Done)
   {
                
    if (m_flag)
    {
     foreach (string sIP in m_computers)
     {
      this.IP=sIP;
      this.m_sendText=m_sendStr;
      this.send();
     }
     m_flag=false; //发送完毕
    }
    Thread.Sleep(20); //防止系统资源耗尽
   }
  }



  /// <summary>
  /// 循环接收
  /// </summary>
  private void Received()
  {
   Thread.Sleep(2000);
   //ASCII 编码
   Encoding ASCII=Encoding.ASCII;
            Thread.Sleep(10); //防止系统资源耗尽
   while (!m_Done)
   {
    
    IPEndPoint endpoint=null;
    if (m_Client!=null && recvThread.IsAlive)
    {
     //接收数据  
     try
     {
      Byte[] data=m_Client.Receive(ref endpoint);
      //得到数据的ACSII的字符串形式
      String strData=ASCII.GetString(data);
      SOCKETEventArrive("receive:"+strData);
     }
     catch 
     {
      //SOCKETEventArrive("receive:Nullerror");
     }
    }
    Thread.Sleep(10); //防止系统资源耗尽
   }
  }
}
}