添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

最近在Socket编程的时候发现只能设置Send和Recieve的Timeout时间,而Connect方法的Timeout是固定的,大概有20-40s,如果用同步方法界面会卡死很长时间

下面搜集了几种通过异步的方式解决此问题的方法:

1.使用BeginConnect方法

IAsyncResult connResult = mySocket.BeginConnect(yourAddress, yourPort, null, null);
//WaitHandle.WaitOne 方法阻止当前线程,直到当前的 WaitHandle 收到信号
connResult.AsyncWaitHandle.WaitOne(2000, true);  //等待2秒
if (!connResult.IsCompleted)
  mySocket.Close();
  //处理连接不成功的动作
  //处理连接成功的动作

这种方法很好的控制了连接超时时间而且代码非常简单,但是界面仍然会有2秒的卡死产生。如果想解决该问题,则需要创建一个额外的线程来执行WaitOne方法。

2.使用ConnectAsync方法

SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.Completed += new EventHandler<SocketAsyncEventArgs>(AsyncConnected);
e.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(yourAddress), yourPort);
mySocket.ConnectAsync(e);

这是一种事件触发的方式,将连接成功后的动作放在Completed事件的处理过程中,从而使界面不会卡死。同时也可以创建一个额外线程来监视连接时间,从而达到控制连接超时的目的。
3.

class TimeOutSocket
    private static bool IsConnectionSuccessful = false;
    private static Exception socketexception;
    private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
    public static TcpClient Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
        TimeoutObject.Reset();
        socketexception = null; 
        string serverip = Convert.ToString(remoteEndPoint.Address);
        int serverport = remoteEndPoint.Port;          
        TcpClient tcpclient = new TcpClient();
        tcpclient.BeginConnect(serverip, serverport,
            new AsyncCallback(CallBackMethod), tcpclient);
        if (TimeoutObject.WaitOne(timeoutMSec, false))
            if (IsConnectionSuccessful)
                return tcpclient;
                throw socketexception;
            tcpclient.Close();
            throw new TimeoutException("TimeOut Exception");
    private static void CallBackMethod(IAsyncResult asyncresult)
            IsConnectionSuccessful = false;
            TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
            if (tcpclient.Client != null)
                tcpclient.EndConnect(asyncresult);
                IsConnectionSuccessful = true;
        catch (Exception ex)
            IsConnectionSuccessful = false;
            socketexception = ex;
        finally
            TimeoutObject.Set();

这里,ManualResetEvent的WaitOne(TimeSpan, Boolean)起到了主要的作用。它将阻止当前线程,直到ManualResetEvent对象被Set或者超过timeout时间。上面的代码中,调用BeginConnect后通过WaitOne方法阻止当前线程,如果在timeoutMSec时间内连接成功,将在CallBackMethod回调中调用TimeoutObject.Set,解除被阻塞的连接线程并返回;否则,连接线程会在等待超时后,主动关闭连接并抛出TimeoutException。
4.

 private string ConnectSocket(IPEndPoint ipep, Socket s)
            string m = "";
                s.Connect(ipep);
            catch (System.Exception ex)
                m = ex.Message;
            return m;
        /// <summary>
        /// 创建TCP连接
        /// </summary>
        /// <returns>连接状态</returns>
        public bool Modbus_TCP_Open()
            int Timeout = 500;
            //创建一个套接字   
            //将服务器IP地址存放在字符串
            //将端口号强制为32位整型,存放在port中
            IPEndPoint ie = new IPEndPoint(IPAddress.Parse(IP_Address), Convert.ToInt32(PC_Port));
            newclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            CSD d = ConnectSocket;
            IAsyncResult iaresult = d.BeginInvoke(ie, newclient, null, null);
            bool connectSuccess = iaresult.AsyncWaitHandle.WaitOne(Timeout, false);
            if (!connectSuccess)
                MessageBox.Show(string.Format("失败!错误信息:{0}", "连接超时"));
                return false;
            //EndInvoke方法一直阻塞,直到被调用的方法执行完毕。会导致用户界面假死
            string m = d.EndInvoke(iaresult);
            if (!string.IsNullOrEmpty(m))
                MessageBox.Show(string.Format("失败!错误信息:{0}", m));
                return false;
            return true;
                    最近在Socket编程的时候发现只能设置Send和Recieve的Timeout时间,而Connect方法的Timeout是固定的,大概有20-40s,如果用同步方法界面会卡死很长时间下面搜集了几种通过异步的方式解决此问题的方法:1.使用BeginConnect方法IAsyncResult connResult = mySocket.BeginConnect(yourAddress, you...
				
.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时控制机制。因此,当服务器未处于监听状态,或者发生网络故障时,客户端连接请求会被迫等待很长一段时间,直到抛出异常。默认的等待时间长达20~30s。.Net Socket库的SocketOptionName.SendTimeout提供了控制发送数据的超时时间,但并非本文讨论的连接请求的超时时间。实现下面是实现的关键代码: 代码如下:class TimeOutSocket{    private static bool I
C#中, 对于Socket的请求,无论是同步还是异步,都没有提供超时机制,SendTimeout,ReceiveTimeout均无用.. 对于需要测试网络是否正常连接的情况下,超时控制很是有用, 如果服务器不存在,或是客户机网络异常,, 在没有设置超时的情况下,,Socket请求需要等40s-70s...终于在网上找到解决的办法。 private readonly ManualResetE...
使用Modbus Poll可以轻松的用PC模拟Modbus主机,可以建立 Modbus RTU Modbus ASCII Modbus-TCP通信。 当使用Modbus TCP通信时,可以根据结点的多少设置一下超时时间,默认可能为:3000ms(3秒)有点长。       毕竟TCP通信不是中断的是事件驱动型的,也就是不可能马上就收到对方的应答,这在实时性方面需要考虑。 设置超时如下
C#Socket编程只能设置Send和Recieve的Timeout时间,而Connect方法的Timeout是固定的,约为22秒,如果用同步方法界面会卡死很长时间,下面介绍两种通过异步的方式解决此问题的方法: 1.使用BeginConnect方法 IAsyncResult connResult = mySocket.BeginConnect(ip, port, null, null); 1、对于短连接, 通过对 Socket 属性ReceiveTimeout 和 SendTimeout 设置恰当的值, 使得程序在进行读/写时超时, 会产生 SocketException 异常, 通过检查这个异常并进行处理,来完成对异常断开的检测处理. 服务端连接处理代码如下: Socket.SetSocketOption(SocketOptionLevel.Socket, Sock...
C# socket连接超时等待问题(转载) 转自:http://www.cnblogs.com/weidagang2046/archive/2009/02/07/1385977.html 作者:RazanPaul 译者:Todd Wei 原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx 您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connec
最近在调试程序的时候,希望1秒钟调用一次 Socket.Receive() 来接收数据。 实际上,应该是说,如果没有数据到来,就是1秒钟一次,如果有数据到来,则收到数据后立即继续接收,然后继续是1秒钟接收一次。C#的相关代码如下:public bool ReadDataForMe(Socket sck, uint waitSec) int rlen = 1; DateTime
今天突然发现c#版本的异步socket模型 没有直接提供timeout配置 测试了一下 有时候一次不成功的连接 等到api最后返回 可能要等20秒以上 所以就stack上面看了一下 发现有人实现过,遂直接上代码 大家需要就拿走吧using System; using System.Net; using System.Net.Sockets;/// <summary> /// Extensions t
之前有一个项目用到Remoting技术,当远程的地址无效或服务器没运行时,方向远程对象方向,会经过几十秒的时间才抛出异常。因为我用的是tcp模式,所以想到可以用socket来测试连接,就可以在调用远程对象方法之前知道远端服务有没有运行。代码如下: public class TcpServiceConnect         protected EventWaitHand
在网上找到很方便的设置办法,分享如下: Socket.SetSocketOption(SocketOptionLevel.Socket,SocketOptionName.ReceiveTimeout,1000); 设置Socket接收超时,时长为1000... 1. 在Visual Studio中创建一个新的C#项目。 2. 在项目中添加一个数据源,选择要连接的数据库类型。 3. 在数据源配置向导中输入数据库连接信息,包括服务器名称、数据库名称、用户名和密码等。 4. 完成数据源配置后,可以在项目中使用ADO.NET提供的类库进行数据库操作,如SqlConnection、SqlCommand、SqlDataReader等。 需要注意的是,连接数据库前需要确保已经安装了相应的数据库驱动程序,如SQL Server需要安装SQL Server驱动程序。