关闭客户端套接字不工作

时间:2015-03-10 18:50:49

标签: sockets tcp

我无法关闭空闲的TCP套接字。我的客户端经常重新连接并从SocketAsynchEventArgs对象池创建一个新套接字。我将所有套接字存储在列表中,并将当前工作套接字存储在哈希表中,但无法关闭现在空闲的套接字。我也在usertoken中存储活动的最后一次。我的计时器每2分钟开火一次。如果活动的最后一次超过6分钟,我希望关闭该套接字并将其返回到池中。贴在下面是我的功能。当空闲时间超过6分钟时,需要以某种方式调用CloseClientSocket函数。有时(不是通过计时器)我可以看到这个代码执行SocketError.TimedOut。接收超时和发送超时设置为60秒进行测试。当发生这种情况时,套接字被释放,一切都很好。所以我需要这个函数从下面粘贴的层函数FireThistimer触发。请帮忙。让我补充一点,如果我从计时器函数调用CloseClientSocket,TCP服务器就会完全停止。

private void CloseClientSocket(SocketAsyncEventArgs e)
{
    try
    {
        var receiveSendToken = (e.UserToken as DataHoldingUserToken);

        {
            Program.testWriter.WriteLine("CloseClientSocket, id " + receiveSendToken.TokenId);
        }
        if (Program.watchThreads == true)   //for testing
        {
            DealWithThreadsForTesting("CloseClientSocket()", receiveSendToken);
        }

        // do a shutdown before you close the socket


        try
        {
            if (Program.watchProgramFlow == true)   //for testing
            {
                Program.testWriter.WriteLine("CloseClientSocket, Shutdown try, id " + receiveSendToken.TokenId + "\r\n");

            }
            removeEntryInHashTableBySocket(e);
            receiveSendToken.unitID = -1;
            receiveSendToken.flagUnitType = -1;
            receiveSendToken.seqIDINT = -1;
            receiveSendToken.needToSendbackKP = false;
            receiveSendToken.needToSendBackACK = false;
            //  receiveSendToken.ACKToSend = null;
            Thread.Sleep(500);
            e.AcceptSocket.Shutdown(SocketShutdown.Both);

        }  // throws if socket was already closed
        catch (Exception xCS)
        {
            Console.WriteLine("Socket is already closed " + xCS.Message);
            if (Program.watchProgramFlow == true)   //for testing
            {
                Program.testWriter.WriteLine("CloseClientSocket, Shutdown catch, id " + receiveSendToken.TokenId + "\r\n");
            }
        }

        //This method closes the socket and releases all resources, both
        //managed and unmanaged. It internally calls Dispose.
        try
        {
            if (e != null)
            {
                e.AcceptSocket.Close();
                //here  to remove from listOfSockets
                if(Program.listOfSockets.Contains(e))
                {
                RemoveFromListOfSocket(e);
                }
            }
        }
        catch (Exception)
        {
            Console.WriteLine("ERROR in Client Close ..");

        }

        //Make sure the new DataHolder has been created for the next connection.
        //If it has, then dataMessageReceived should be null.
        if (receiveSendToken.theDataHolder.dataMessageReceived != null)
        {
            receiveSendToken.CreateNewDataHolder();
        }

        // Put the SocketAsyncEventArg back into the pool,
        // to be used by another client. This 
        this.poolOfRecSendEventArgs.Push(e);

        // decrement the counter keeping track of the total number of clients 
        //connected to the server, for testing
        Interlocked.Decrement(ref this.numberOfAcceptedSockets);

        if (Program.watchConnectAndDisconnect == true)   //for testing
        {
            Program.testWriter.WriteLine(receiveSendToken.TokenId + " disconnected. " + this.numberOfAcceptedSockets + " client(s) connected.");
        }

        //Release Semaphore so that its connection counter will be decremented.
        //This must be done AFTER putting the SocketAsyncEventArg back into the pool,
        //or you can run into problems.
        this.theMaxConnectionsEnforcer.Release();
    }
    catch (Exception What1)
    {

        Console.WriteLine(What1.Message);
    }
}


private void FireThisTimer(object source, ElapsedEventArgs e)
{
    try
    {
        DataHoldingUserToken theUserTokenHere;
        Int64 unitInKey;
        int listcount4 = Program.listOfSockets.Count;
        Console.WriteLine("Timer fired with sockets =  " + listcount4.ToString());
        SocketAsyncEventArgs[] array4Purge = new SocketAsyncEventArgs[listcount4];
        Program.listOfSockets.CopyTo(array4Purge);
        foreach (SocketAsyncEventArgs socket4 in array4Purge)
        {
            try
            {
                theUserTokenHere = (DataHoldingUserToken)socket4.UserToken;
                unitInKey = theUserTokenHere.unitID;
                double timeSincePrevData = calcTimeInterval(theUserTokenHere);
                if (timeSincePrevData > 6)
                {
                    Console.WriteLine("Found idle socket with unitid =" + unitInKey);

                    socket4.SocketError = SocketError.TimedOut;
                    socket4.AcceptSocket.Shutdown(SocketShutdown.Both);

                    theUserTokenHere.Reset();
                }
            }
            catch (Exception xVB)
            {
                Console.WriteLine("Continuing after exception in for loop "+xVB.Message);
                continue;
            }
        }
        Console.WriteLine("Sockets at the end of timer event = " + Program.listOfSockets.Count.ToString());
    }
    catch (Exception xCE)
    {
        Console.WriteLine("Timer Exception is " + xCE.Message);
    }

}

0 个答案:

没有答案