当前位置: 代码迷 >> C# >> socket 超时有关问题
  详细解决方案

socket 超时有关问题

热度:77   发布时间:2016-05-05 03:01:51.0
socket 超时问题

        private Socket tcpAsyCl;
        /// <summary>Start connection to slave.</summary>
        /// <param name="ip">IP adress of modbus slave.</param>
        /// <param name="port">Port number of modbus slave. Usually port 502 is used.</param>
        public void connect(string ip, ushort port)
        {
            try
            {
                IPAddress _ip;
                if (IPAddress.TryParse(ip, out _ip) == false)
                {
                    IPHostEntry hst = Dns.GetHostEntry(ip);
                    ip = hst.AddressList[0].ToString();
                }
                // ----------------------------------------------------------------
                // Connect asynchronous client
                tcpAsyCl = new Socket(IPAddress.Parse(ip).AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                tcpAsyCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout);
                tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout);
                tcpAsyCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
                // ----------------------------------------------------------------
                // Connect synchronous client
                tcpSynCl = new Socket(IPAddress.Parse(ip).AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                tcpSynCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, _timeout);
                tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, _timeout);
                tcpSynCl.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.NoDelay, 1);
                _connected = true;
            }
            catch (System.IO.IOException error)
            {
                _connected = false;
                throw (error);
            }
        }


如果网络不通
 tcpAsyCl.Connect(new IPEndPoint(IPAddress.Parse(ip), port)); 
这句话会很久才会抛异常
可不可以自己定义超时时间 自己抛异常
------解决思路----------------------
SendTimeout
------解决思路----------------------
Socket.SendTimeout
------解决思路----------------------
对于任何异步的操作,你都可以定义一个定时器来尽早知道“超时”。这要自己设计几行代码来处理业务逻辑(包括在判断超时之后,万一又执行了操作该怎么办的问题)。
------解决思路----------------------
嗯当然,我说的“定时器”是广义的。例如假设调用线程必须阻塞,那么  ManualResetEvent.WaiOne(1500) 这中阻塞方式也算。
------解决思路----------------------
.net socket没有提供连接超时的设置,但是也可以用其他方法解决
可以参考这篇
《C# Socket连接请求超时机制》
http://www.cnblogs.com/weidagang2046/archive/2009/02/07/1385977.html
  相关解决方案