/// <summary> /// 从Tcp服务端获取信息的回调函数 /// </summary> /// <param name="ar"></param> private void ReceiveCallBack(IAsyncResult ar) { DerivedUdpClient client = (DerivedUdpClient)ar.AsyncState; try { //IPEndPoint point = RemoteEndPoint; byte[] recdata = BaseClient.EndReceive(ar, ref remote_endpoint); //RemoteEndPoint = point; if (recdata.Length > 0) { if (DataReceived != null) { DataReceived.BeginInvoke(client.Name, new Events.DataReceivedEventArgs(recdata), null, null); //异步输出数据 } raiser.Click(); if (ReceiveRestTime > 0) { Thread.Sleep(ReceiveRestTime); } if (AutoReceive) { BaseClient.BeginReceive(new AsyncCallback(ReceiveCallBack), client); } } } catch (Exception ex) { FileClient.WriteExceptionInfo(ex, string.Format("从TcpServer获取数据的过程中出错:IP地址{0},端口{1}", ServerIp, ServerPort), true); } }
/// <summary> /// 构造器,以指定本地IP和端口号初始化一个未连接DerivedTcpClient对象,决定本地端口和是否接收数据 /// </summary> /// <param name="local_ip">本地IP</param> /// <param name="local_port">本地端口号</param> /// <param name="auto_receive">是否自动接收</param> /// <param name="hold_port">重新连接时是否维持相同本地端口</param> public DerivedUdpClient(string local_ip, int local_port, bool auto_receive, bool hold_port) { LocalIp = local_ip; LocalPort = local_port; AutoReceive = auto_receive; HoldLocalPort = hold_port; LastErrorMessage = string.Empty; Name = string.Empty; ReceiveRestTime = 0; ReconnectWhenReceiveNone = false; RaiseThreshold = 5000; RaiseInterval = 5000; raiser.ThresholdReached += new TimerEventRaiser.ThresholdReachedEventHandler(Raiser_ThresholdReached); //if (!string.IsNullOrWhiteSpace(local_ip) && local_port > 0) //BaseClient = new UdpClient(new IPEndPoint(IPAddress.Parse(local_ip), local_port)); BaseClient = !string.IsNullOrWhiteSpace(LocalIp) && LocalPort > 0 ? new UdpClient(new IPEndPoint(IPAddress.Parse(LocalIp), LocalPort)) : new UdpClient(); IsStartListening = true; raiser.Run(); SetName(); try { if (AutoReceive) { BaseClient.BeginReceive(new AsyncCallback(ReceiveCallBack), this); } } catch (Exception) { } }
/// <summary> /// UDP重新连接方法 /// </summary> private void TcpAutoReconnect() { while (true) { Thread.Sleep(1000); //假如属性提示未连接,则UDP重连线程挂起 if (!IsConnected) { Auto_UdpReconnect.WaitOne(); } //假如属性提示已连接但实际上连接已断开,尝试重连 //else if (IsConnected && !IsSocketConnected()) else if (IsConnected && !IsConnected_Socket) { string temp = string.Format("UDP主机地址:{0},端口号:{1}", ServerIp, ServerPort); //UDP连接的主机地址与端口 LastErrorMessage = "UDP连接意外断开,正在尝试重连。" + temp; FileClient.WriteFailureInfo(LastErrorMessage); try { BaseClient.Close(); BaseClient = HoldLocalPort ? new UdpClient(LocalEndPoint) : new UdpClient(); BaseClient.Connect(ServerIp, ServerPort); SetName(); //重连次数+1,同时调用事件委托 ReconnTimer++; if (ReconnTimerChanged != null) { ReconnTimerChanged.BeginInvoke(Name, ReconnTimer, null, null); } if (Connected != null) { Connected.BeginInvoke(Name, new EventArgs(), null, null); } //NetStream = BaseClient.GetStream(); if (AutoReceive) { BaseClient.BeginReceive(new AsyncCallback(ReceiveCallBack), this); } //NetStream.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(TcpCallBack), this); //IsSocketConnected(); FileClient.WriteFailureInfo("UDP重新连接成功。" + temp); } //假如出现异常,将错误信息写入日志并进入下一次循环 catch (Exception e) { LastErrorMessage = string.Format("UDP重新连接失败:{0}。", e.Message) + temp; FileClient.WriteExceptionInfo(e, LastErrorMessage, false); continue; //TODO: 是否抛出异常? //throw; //假如不需要抛出异常,注释此句 } } } }
/// <summary> /// 利用特定的本地端口与UDP服务端连接 /// </summary> /// <param name="server">UDP服务端IP</param> /// <param name="port">端口号</param> /// <param name="localIp">本地IP</param> /// <param name="localPort">指定的本地端口(假如小于等于0则随机)</param> /// <returns>假如建立连接成功,返回1,否则返回0</returns> public int Connect(string server, int port, string localIp, int localPort) { //尝试建立连接 int result = 1; try { ServerIp = server; ServerPort = port; LocalIp = localIp; LocalPort = localPort; if (BaseClient == null) { BaseClient = !string.IsNullOrWhiteSpace(LocalIp) && LocalPort > 0 ? new UdpClient(new IPEndPoint(IPAddress.Parse(LocalIp), LocalPort)) : new UdpClient(); } BaseClient.Connect(ServerIp, ServerPort); SetName(); //修改连接名称 //重置重连次数,同时调用事件委托 ReconnTimer = 0; if (ReconnTimerChanged != null) { ReconnTimerChanged.BeginInvoke(Name, ReconnTimer, null, null); } //BaseClient.ReceiveBufferSize = ReceiveBufferSize; //接收缓冲区的大小 //NetStream = BaseClient.GetStream(); //发送与接收数据的数据流对象 } catch (Exception e) { LastErrorMessage = string.Format("无法建立UDP连接,IP{0},端口号{1}:{2}", ServerIp, ServerPort, e.Message); FileClient.WriteExceptionInfo(e, LastErrorMessage, false); Close(); result = 0; //throw; //假如不需要抛出异常,注释此行 } IsConnected = true; //IsSocketConnected(); if (IsConnected) { //调用Tcp连接事件委托 if (Connected != null) { Connected.BeginInvoke(Name, (new EventArgs()), null, null); } if (Thread_Reconnect == null) { Auto_UdpReconnect = new AutoResetEvent(true); Thread_Reconnect = new Thread(new ThreadStart(TcpAutoReconnect)) { IsBackground = true }; //Thread_TcpReconnect.IsBackground = true; Thread_Reconnect.Start(); } else { Auto_UdpReconnect.Set(); } //if (AutoReceive) try { BaseClient.BeginReceive(new AsyncCallback(ReceiveCallBack), this); } catch (Exception) { } } return(result); }