由于项目中部分代码是别人完成的,现由我接管,但紧张的编码工作基本完成后,我研究前任牛人的代码中发现有很多通讯的地方都有用到ReceiveTimeout和SendTimeout,仔细查读了一些资料才明白,ReceiveTimeout和SendTimeout的作用.
MSDN中的注释:ReceiveTimeout 属性确定 Read 方法在能够接收数据之前保持阻塞状态的时间量。这一时间的度量单位为毫秒。如果超时在 Read 成功完成之前到期,TcpClient 将引发 SocketException。默认为无超时。.
在通讯过程中,由于客户端是周期性地向服务器请求数据,若客户端的请求指令或是服务端发来的数据包丢失的话,那么客户端将一直等待,陷入假死状态。由于默认为无超时,所以一定要记得设定客户端接收的超时时间,若服务器端无相应,客户端应该抛出异常,而不是毫无意义的等待。
请参考下面的代码.
using System;using System.Text;using System.Net;using System.Net.Sockets;using YD.ZYCAlarm.Buffer;namespace YD.ZYCAlarm.UDPCommunicate{/// <summary>/// SendCommand 的摘要说明。/// </summary>public class SendCommand{/// <summary>/// 要发送的命令文本/// </summary>private string m_CmdText;/// <summary>////// </summary>private static readonly int BUF_SIZE=0x10000;/// <summary>/// 本地UDP对象/// </summary>private Socket m_Client ;/// <summary>/// 本地端口(也可以不设)/// </summary>private int m_LocalPort;/// <summary>/// 远程端口/// </summary>private int m_RemotePort ;/// <summary>/// 远程IP/// </summary>private string m_RemoteIP ;/// <summary>/// 对方网络节点/// </summary>private IPEndPoint m_RemoteEP ;public SendCommand( string strIP,int iPort,string strCmd ){this.m_RemoteIP = strIP ;this.m_RemotePort = iPort;this.m_CmdText = strCmd;m_RemoteEP = new IPEndPoint(IPAddress.Parse( m_RemoteIP ) , m_RemotePort) ;}private void ConnectToServer(){m_Client=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);m_Client.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,3000);}public bool Send(){ConnectToServer();try{Byte[] sendBytes = Encoding.ASCII.GetBytes(this.m_CmdText);this.m_Client.SendTo(sendBytes ,sendBytes.Length,SocketFlags.None,m_RemoteEP) ;//接收服务端的回应的成功信息return Receive();}catch{return false ;}}private bool Receive(){byte[] buf=new byte[BUF_SIZE];EndPoint remoteEndPoint=new IPEndPoint(IPAddress.Any,0);try{int receive = this.m_Client.ReceiveFrom(buf,ref remoteEndPoint) ;string strData= Encoding.ASCII.GetString(buf,0,receive);if(strData == "OK"){return true ;}else{return false ;}}catch{return false ;}finally{this.m_Client.Close();this.m_Client = null ;}}public void Dispose(){if(this.m_Client != null){this.m_Client.Close();this.m_Client = null;}}}}