如何发现Socket.Select()报告错误的原因

时间:2009-02-16 10:49:37

标签: c# sockets

我在System.Net.Sockets.Socket上调用Bind()然后调用Listen()。 这些调用都没有抛出异常。

稍后,我打电话给:

Socket.Select(myreadlist,mywritelist,myerrorlist,0);

myreadlist和myerrorlist包含有问题的套接字。 通过离开套接字选择报告我的套接字有错误 在errorList中,而不是从列表中删除它。该计划无处可寻 抛出SocketException。

我似乎无法弄清楚我应该问系统的正确方法: “好吧,所以 出了什么问题?”

有人知道吗?

谢谢卢卡斯

编辑:为select +添加第4个参数= 0更好地解释了select()如何告诉我发生了错误。

2 个答案:

答案 0 :(得分:1)

我不知道C#,但我确实知道UNIX套接字。我的第一个想法是你在选择读取之前没有在套接字上调用accept()但是(这证明我对插槽的了解比我想象的少)你可以在listen状态中选择以查看哪些套接字可以被接受。哦,我们生活和学习,即使在我年事已高: - )

无论如何,提到通过Google找到的MSDN文档here(“c#”socket bind listen select),它指出:

If you receive a SocketException, use SocketException.ErrorCode to obtain the specific error code. Once you have obtained this code, you can refer to the Windows Socket Version 2 API error code documentation in MSDN for a detailed description of the error.

这些错误代码似乎记录在案here,可通过Google搜索找到(MSDN中的Windows Socket Version 2 API错误代码文档)。

我提到Google搜索条款,以防MSDN移动他们的网页。我将从捕获的异常中输出错误代码,然后在第二个链接的列表中查找它以获取失败的实际原因。一旦我们知道了这一点,我们就可以进一步帮助你(或者它可能变得非常明显,你不需要再次问我们了: - )。

有一件事似乎不协调:调用的原型有第四个参数,如果没有活动则要等待几微秒。您在问题中的代码没有。现在,正如我所说,我对C#知之甚少,所以它可能默认为某些东西(或者你可能只是意外地将它排除在外)。

但如果您使用-1(或默认为-1),我会注意一个已知错误:请参阅here了解详情,但它基本上意味着-1立即返回而不是永远等待。解决方法是使用-2来给你一个小时左右的时间,但你仍然需要照顾它可能会返回的事实,即使没有活动。

如果抛出异常,只是在myerrorlist中设置错误指示,则这是一个更为棘手的问题。我看不出任何文档显示如何轻松搞清楚,但我会看看这些可能性。

  • 您可以调用WSA函数(例如,WSAGetLastError())来解决它。我不确定C#有多容易。您可以尝试accept()错误的套接字,看看是否为您提供了一个例外情况,详细说明了它出现问题的原因。
  • Socket类有一个Handle成员,它是套接字的操作系统句柄。可以通过以下方式提取错误信息。
  • 您是否考虑过使用线程进行连接处理并完全绕过select()的使用(即仅使用accept()而是绕过多个线程)?

我发现的另一件事与套接字调试有关。 This page底部有一个部分,显示了如何进行网络跟踪。 .NET 2显然不支持select(),但在最新版本中可能已经改变了。

答案 1 :(得分:0)

Select()调用的文档说明了这一点:

  

如果您对Connect进行了非阻塞调用,则checkerror参数会识别未成功连接的套接字。

在SelectError模式下,Poll()方法的文档(它建议用于确定单个套接字的状态)说:

  

如果处理未阻止的Connect且连接失败,则为true;   -要么-   如果未设置OutOfBandInline并且带外数据可用,则为true;否则为false。   否则,返回false。

基于此,我想说这些是套接字指示错误状态而没有先前抛出异常的唯一两个条件。你没有提到调用Connect(),但如果你这样做,我会验证它实际上正在建立连接。带外数据非常罕见,但也许你的另一端套接字正在做一些奇怪的事情。