How to set a timeout of Socket.ConnectAsync?

守給你的承諾、 提交于 2019-12-04 12:25:53

I've figured out a solution.
first add all created sockets to a list of type SocketAsyncEventArgs or type ofSocket or
then use System.Timers.Timer to close all pending connection and the connected one after when the timer ticks which is after 5 seconds. (timer.Interval = 5000).

Client Code:

   //I've changed my console application to Winform
   public ServerDiscovery()
    {
        InitializeComponent();
        timer.Elapsed += timer_tick;
    }

    System.Timers.Timer timer = new System.Timers.Timer(5000);
    List<SocketAsyncEventArgs> list = new List<SocketAsyncEventArgs>();

    private void btnRefresh_Click(object sender, EventArgs e)
    {
        timer.Start();
        Parallel.For(1, 255, (i, loopState) =>
        {
            ConnectTo("192.168.1." + i);
        });
    }

    private void ConnectTo(string ipAdd)
    {
        Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        SocketAsyncEventArgs e = new SocketAsyncEventArgs();
        e.RemoteEndPoint = new IPEndPoint(IPAddress.Parse(ipAdd), 9990);
        e.UserToken = s;
        e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
        list.Add(e);      // Add to a list so we dispose all the sockets when the timer ticks.
        s.ConnectAsync(e);
    }

    private void e_Completed(object sender, SocketAsyncEventArgs e)
    {
        if (e.ConnectSocket != null)     //if there's a connection Add its info to a listview
        {
            StreamReader sr = new StreamReader(new NetworkStream(e.ConnectSocket));
            ListViewItem item = new ListViewItem();
            item.Text = sr.ReadLine();
            item.SubItems.Add(((IPEndPoint)e.RemoteEndPoint).Address.ToString());
            item.SubItems.Add("Online");
            AddServer(item);
        }
    }

    delegate void AddItem(ListViewItem item);
    private void AddServer(ListViewItem item)
    {
        if (InvokeRequired)
        {
            Invoke(new AddItem(AddServer), item);
            return;
        }
        listServer.Items.Add(item);
    }

    private void timer_tick(object sender, EventArgs e)
    {
        timer.Stop();
        foreach (var s in list)
        {
            ((Socket)s.UserToken).Dispose();     //disposing all sockets that's pending or connected.
        }
    }

zmbq

I couldn't find any built-in timeout mechanism. You should set a timer and abort the connections when it triggers. Something similar to this: How to configure socket connect timeout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!