如何检查服务器是否正在侦听而不进行异常处理
我正在开发两个使用 TCP 相互连接的应用程序。在某一时刻,其中一个应用程序尝试使用 TcpClient 进行连接,但不能保证另一个应用程序已开始侦听(使用 TcpListener)。
我的第一次尝试是这样的:
TcpClient c = null;
while (true)
{
try
{
c = new TcpClient();
c.NoDelay = true;
c.Connect( ip, port );
break;
}
catch (SocketException ex)
{
Console.WriteLine(string.Format("Could not connect to {0}:{1}, retrying...", ip, port));
Thread.Sleep( 500 );
}
}
然而,这样做的问题是它依赖于异常处理,这对我来说有点麻烦,因为我设置了 VS 来捕获任何抛出的异常(“调试 -> 异常... “ 菜单)。所以每次它尝试连接时,它都会中断 VS,我必须按“继续”。
我得到的例外是:
无法建立连接,因为目标机器主动拒绝127.0.0.1:50000
我想有一种方法可以检查服务器是否正在侦听特定端口,而无需实际尝试连接到它。我知道仅仅检查是不够的 - 服务器可能会在检查和连接尝试之间停机,但在我开发它时对我来说仍然会好得多。
或者类似这样的事情:
TcpClient tcpClient = new TcpClient();
while ( !tcpClient.TryConnect(....) )
{ Thread.Sleep(1000); }
与此类似:
if (bool.TryParse( "false" ))
{ ... }
我也尝试使用异步方法(开始/结束连接)并手动设置 ManualResetEvent 的超时,但这也不起作用。我已经在互联网上搜索过,但找不到解决这个问题的方法,这就是为什么我最终在这里发帖:)
I'm working on two apps that connect to eachother using TCP. At one point, one of them is trying to connect using a TcpClient, but the other app is not guaranteed to have started listening yet (using TcpListener).
My first attempt was this:
TcpClient c = null;
while (true)
{
try
{
c = new TcpClient();
c.NoDelay = true;
c.Connect( ip, port );
break;
}
catch (SocketException ex)
{
Console.WriteLine(string.Format("Could not connect to {0}:{1}, retrying...", ip, port));
Thread.Sleep( 500 );
}
}
However, the problem with this is that it relies on exception handling which is a bit of a nuisance for me, because I have VS set up to catch any thrown exceptions ("Debug -> Exceptions..." menu). So every time it tries to connect, it breaks into VS and I have to press continue.
The exception I get is:
No connection could be made because the target machine actively refused it 127.0.0.1:50000
I would imagine that there would be a way to check if a server is listening on a specific port without actually trying to connect to it. I understand that just checking wouldn't be enough anyway - the server could go down between the check and the connect attempt, but it would still be much better for me while I'm developing it.
Or something like this:
TcpClient tcpClient = new TcpClient();
while ( !tcpClient.TryConnect(....) )
{ Thread.Sleep(1000); }
Analogous to this:
if (bool.TryParse( "false" ))
{ ... }
I also tried using async methods (Begin/End Connect) and setting the timeout for the ManualResetEvent manually, but that didn't work either. I've scoured the internets but I haven't been able to find a solution to this problem, which is why I'm finally posting here :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是 VS 因异常而中断?你总是可以让 VS 忽略特定的异常系列。
在 VS 的“调试”菜单中,选择“异常...”,然后在出现的对话框中您可以对此进行控制。
The problem being that VS is breaking on the Exception? You you can always have VS ignore a specific family of Exceptions.
In VS, in the Debug Menu, choose "Exceptions..." and in the dialog presented you can control this.
我本来打算建议不要捕获异常,所以在我建议我自己测试它之前,如果您将其设置为抛出所有异常,即使您不抛出异常,它仍然会抛出所有异常。我必须同意 Shiv Kumar 的观点,要么在调试应用程序时调整您的设置,要么接受您正在做的事情的限制。
bool.TryParse 起作用的原因是它验证每个字符,类似于 Int32.TryParse 如何确保字符串中的每个字符是 0-9 或任何其他有效的数字符号。
您当然可以编写自己的网络类,并且在连接失败时不抛出异常。
TryParse 不会抛出异常,如果您通过 try{ 使用 bool.Parse ,则必须捕获抛出的任何异常}catch{} 否则,如果您尝试解析不是布尔值的内容,它将引发未处理的异常。 TryParse 是在 .NET 历史上后来添加的,Parse 更像是经典方法,允许程序员处理所有意外输入并在尝试解析数据之前验证输入。
我应该补充一点,如果 TryParse 无法解析方法结果为 false 且我确实相信的输出变量为 false 时的值,则 TryParse 将返回 false。至少 Int32
http://msdn.microsoft.com/en-us/library/system.boolean.tryparse.aspx
我想指出 TryParse 和 Parse 如何工作的重点是,与 TcpClient 相比,它们是完全不同的野兽。我想我应该澄清基本验证过程是相似的,除了一个抛出异常而另一个不抛出异常,当然一个返回实际解析的内容。
I was going to suggest not catching an exception, so before I suggested that I test it myself, and if you set it to throw all exceptions even if you don't throw an exception its all exceptions are still being thrown. I will have to agree with Shiv Kumar, either adjust your settings while you debug your application, or accept the limitations of what you are doing.
The reason bool.TryParse works is it verifys each and every character, similarly to how Int32.TryParse makes sure that each character in the string is 0-9 or any other valid numerical symbol.
You could of course write your own networking class and not throw an exception when the connection fails.
TryParse will not throw an exception, you must catch any exception that is thrown if you use bool.Parse by try{}catch{} otherwise if you attempt to parse something that is not a boolean value it will throw an unhandled exception. TryParse was added later in the history of .NET, Parse is more of the classic method, allowing the programmer to handle all unexpected input and to validate input before trying to parse the data.
I should add that TryParse will return false if its unable to parse the value at both the method's result is false and the out variable I do believe is false.This is at least the case with Int32
http://msdn.microsoft.com/en-us/library/system.boolean.tryparse.aspx
I guess the point of pointing out how TryParse and Parse works is that they are entirely different beasts compare to TcpClient. I suppose I should clarify that the basic validation process is similar, except one throws an exception and the other one doesn't and of course one returns what was actually parsed.