Search code examples
c#webservice-clientwsastartup

Webservice call results in WSAStartUp Error after 3 succesfull calls


I have a C# winforms application which functions as a server for some access devices through a .DLL.

User access is determined by sending input to a webservice (set up as a webreference), and returning the results to the devices, however in case of a timeout, the app disconnects all devices, stops the server, and starts up a backgroundworker. The backgroundworker retries the connection to the webservice, and if succesfull, starts up the server again, and reconnects the devices.

This all works very well, but unfortunately, on the third fourth or fifth time, the backgroundworker tries to reconnect to the webservice, the connection fails with an exception "Either the application has not called WSAStartup, or WSAStartup failed" . each following try, gets a simmilar error.

Here is the source for the backgroundworker, its very simple code:

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);
            }
        }

As a side note, the webservice works like a charm otherwise.


Solution

  • I ended up solving this by calling WSAstartup manually in the exception handler, and retrying.

    Import of 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>
    }
    

    And simply use the SocketInitialize() Method.

    bool startup = WSAinterop.SocketInitialize();