1

我有一个 C# winforms 应用程序,它通过 .DLL 作为某些访问设备的服务器。

用户访问是通过将输入发送到 Web 服务(设置为 Web 引用)并将结果返回到设备来确定的,但是在超时的情况下,应用程序会断开所有设备,停止服务器并启动后台工作程序。后台工作人员重试与 Web 服务的连接,如果成功,则再次启动服务器并重新连接设备。

这一切都很好,但不幸的是,在第三四次或第五次,backgroundworker 尝试重新连接到 web 服务,连接失败并出现异常"Either the application has not called WSAStartup, or WSAStartup failed"。每次以下尝试,都会得到一个类似的错误。

这是 backgroundworker 的源代码,它的代码非常简单:

private void backgroundWorkerStopServer_DoWork(object sender, DoWorkEventArgs e)
    {
        System.Threading.Thread.Sleep(2000);
        stopServer();

        NewDoorCheck.Doorcheck ndoorcheck = new NewDoorCheck.Doorcheck();
        ndoorcheck.Timeout = 15000;

        bool disconnected = true;

        while (disconnected)
        {
            try
            {

                ndoorcheck.WebserviceIsUp();

                UpdateLog("Connected web");
                disconnected = false;
                startServer();
            }
            catch (Exception ex)
            {

                UpdateLog(ex.Message);
                UpdateLog(ex.StackTrace);
                UpdateLog("Still Down");
                System.Threading.Thread.Sleep(60000);
            }
        }

附带说明一下,Web 服务在其他方面就像一个魅力。

4

1 回答 1

0

我最终通过在异常处理程序中手动调用 WSAstartup 并重试解决了这个问题。

Winsock的进口

class WSAinterop
{
    [StructLayout(LayoutKind.Sequential)]
    internal struct WSAData
    {
        public short wVersion;
        public short wHighVersion;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
        public string szDescription;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
        public string szSystemStatus;
        public short iMaxSockets;
        public short iMaxUdpDg;
        public int lpVendorInfo;
    }


    [DllImport("wsock32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    internal static extern int WSAStartup(
          [In] short wVersionRequested,
          [Out] out WSAData lpWSAData
          );

    [DllImport("wsock32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
    internal static extern int WSACleanup();

    private const int IP_SUCCESS = 0;
    private const short VERSION = 2;
    public static bool SocketInitialize()
    {
        WSAData d;

        return WSAStartup(VERSION, out d) == IP_SUCCESS;
    }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
}

并且只需使用 SocketInitialize() 方法。

bool startup = WSAinterop.SocketInitialize();
于 2014-11-03T10:53:08.847 回答