如何设置Socket.ConnectAsync的超时时间?
我一直在阅读关于如何检查局域网上特定端口上的所有监听服务器,最后我写了一些代码,它可以工作,因为我想要的。
我使用System.Threading.Tasks.Parallel尽可能快地连接到所有254个IP地址
ex: 192.168.1。 - 192.168.1。如何设置Socket.ConnectAsync的超时时间?
我需要做的是为这些连接尝试超时,因为它需要约15-20秒打印:“连接失败”,当它失败..所以我该怎么办呢?
这里的客户端代码:
static void Main(string[] args)
{
Console.WriteLine("Connecting to IP addresses has started. \n");
Parallel.For(1, 255, i =>
{
Connect("192.168.1." + i);
});
Console.ReadLine();
}
private static void Connect(string ipAdd)
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
IPEndPoint ipEnd = new IPEndPoint(IPAddress.Parse(ipAdd), 9990);
e.RemoteEndPoint = ipEnd;
e.UserToken = s;
e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
Console.WriteLine("Trying to connect to : " + ipEnd);
s.ConnectAsync(e);
}
private static void e_Completed(object sender, SocketAsyncEventArgs e)
{
if (e.ConnectSocket != null)
{
StreamReader sr = new StreamReader(new NetworkStream(e.ConnectSocket));
Console.WriteLine("Connection Established : " + e.RemoteEndPoint + " PC NAME : " + sr.ReadLine());
}
else
{
Console.WriteLine("Connection Failed : " + e.RemoteEndPoint);
}
}
服务器代码:
static void Main(string[] args)
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ep = new IPEndPoint(IPAddress.Any,9990);
server.Bind(ep);
server.Listen(100);
Socket client = server.Accept();
NetworkStream stream = new NetworkStream(client);
StreamWriter sw = new StreamWriter(stream)
sw.WriteLine(System.Environment.MachineName);
sw.Flush();
sw.Dispose();
stream.Dispose();
client.Dispose();
server.Dispose();
}
如果有使得它更告诉我任何提示或通知。我正在使用[.Net 4.0]套接字TCP
对不起,我的英语不好,在此先感谢..
我已经想出了一个解决方案。
首先创建的套接字添加类型的列表的SocketAsyncEventArgs或插座或
的类型 然后使用System.Timers.Timer以关闭所有挂起连接,并且当计时器滴答后的连接的一个,其是在5秒后。 (timer.Interval = 5000)。
客户端代码:
//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.
}
}
我找不到任何内置的超时机制。您应该设置一个计时器并在触发时中止连接。类似的东西:How to configure socket connect timeout
我不确定..创建一个外部计时器喜欢创建一个新的线程..它似乎不好创建254个计时器 – 2012-03-16 06:33:38
也许我会为所有他们设置一个计时器..但我仍然更喜欢一个更好的主意 – 2012-03-16 06:35:36
您只需要一个计时器,因为它对所有连接都是相同的超时时间。 – zmbq 2012-03-16 07:47:39
15-20秒似乎是合理的一个连接尝试和254次的尝试非常好。如果服务器关闭,我的浏览器花费的时间比“旋转箭头”模式中的时间要长。 – 2012-03-16 08:24:01
实际上,如果链路有拨号调制解调器,则20秒太短。幸运的是,这样的恐怖事件几乎全部消失了。 – 2012-03-16 08:27:00
@MartinJames这是一个局域网,正如我所提到的..大多数显示主机可用的游戏和应用程序..在不到10秒内给出结果。像[pc任何地方,netsupport,半衰期..等等]我知道他们使用更好的算法和方法来得到那个..但我需要它在很短的时间 – 2012-03-16 08:32:14