删除空闲插槽

时间:2015-02-22 09:57:21

标签: c# sockets

在C#Asynch套接字服务器中 - 我需要识别空闲连接并将其删除。我怎么做?我的客户端具有我在DataHoldingUserToken中设置的唯一ID - 同一客户端可能会丢弃先前的连接并创建一个新连接。那时我想到达服务于先前连接的套接字并处理该套接字并将其返回到池中。我如何实现这一目标?

我的代码在这里

    class DataHoldingUserToken
{
    internal Mediator theMediator;
    internal DataHolder theDataHolder;
   // internal dataProcessorAtrack AtrackProcessorHere;

    internal Int32 socketHandleNumber;

    internal readonly Int32 bufferOffsetReceive;
    internal readonly Int32 permanentReceiveMessageOffset;
    internal readonly Int32 bufferOffsetSend;

    public bool needToSendbackKP;
    public bool needToSendBackACK;
    public bool sendBackSameSignal;



    public int flagUnitType = -1;
    public Int64 unitID = -1;
    public Int32 seqIDINT = -1;
    public byte[] ACKToSend;

    private Int32 idOfThisObject; //for testing only   
    private object lockerForTokenList = new object();

    internal Int32 lengthOfCurrentIncomingMessage;

    //receiveMessageOffset is used to mark the byte position where the message
    //begins in the receive buffer. This value can sometimes be out of
    //bounds for the data stream just received. But, if it is out of bounds, the 
    //code will not access it.
    internal Int32 receiveMessageOffset;        
    internal Byte[] byteArrayForPrefix;        
    internal readonly Int32 receivePrefixLength;
    internal Int32 receivedPrefixBytesDoneCount = 0;
    internal Int32 receivedMessageBytesDoneCount = 0;
    //This variable will be needed to calculate the value of the
    //receiveMessageOffset variable in one situation. Notice that the
    //name is similar but the usage is different from the variable
    //receiveSendToken.receivePrefixBytesDone.
    internal Int32 recPrefixBytesDoneThisOp = 0;

    internal Int32 sendBytesRemainingCount;
    internal readonly Int32 sendPrefixLength;
    internal Byte[] dataToSend;
    internal Int32 bytesSentAlreadyCount;

    //The session ID correlates with all the data sent in a connected session.
    //It is different from the transmission ID in the DataHolder, which relates
    //to one TCP message. A connected session could have many messages, if you
    //set up your app to allow it.
    private Int32 sessionId;                

    public DataHoldingUserToken(SocketAsyncEventArgs e, Int32 rOffset, Int32 sOffset, Int32 receivePrefixLength, Int32 sendPrefixLength, Int32 identifier)
    {
        this.idOfThisObject = identifier;

        //Create a Mediator that has a reference to the SAEA object.
        this.theMediator = new Mediator(e);
        this.bufferOffsetReceive = rOffset;
        this.bufferOffsetSend = sOffset;
        this.receivePrefixLength = receivePrefixLength;
        this.sendPrefixLength = sendPrefixLength;
        this.receiveMessageOffset = rOffset + receivePrefixLength;
        this.permanentReceiveMessageOffset = this.receiveMessageOffset;
        this.needToSendbackKP = false;
        this.needToSendBackACK = false;
      //  this.AtrackProcessorHere = new dataProcessorAtrack();

    }

    //Let's use an ID for this object during testing, just so we can see what
    //is happening better if we want to.
    public Int32 TokenId
    {
        get
        {
            return this.idOfThisObject;
        }
    }

    internal void CreateNewDataHolder()
    {
        theDataHolder = new DataHolder();
    }

    //Used to create sessionId variable in DataHoldingUserToken.
    //Called in ProcessAccept().
    internal void CreateSessionId()
    {
        sessionId = Interlocked.Increment(ref Program.mainSessionId);                        
    }


    public Int32 SessionId
    {
        get
        {
            return this.sessionId;
        }
    }

    public void Reset()
    {
        this.receivedPrefixBytesDoneCount = 0;
        this.receivedMessageBytesDoneCount = 0;
        this.recPrefixBytesDoneThisOp = 0;
        this.receiveMessageOffset = this.permanentReceiveMessageOffset;
       // this.needToSendBackACK = false;
       // this.needToSendbackKP = false;

    }

}

}

// AddTokenToList在消息处理程序内为新连接上的第一个传入数据启动

bool incomingTcpMessageIsReady =  messageHandler.HandleMessage(receiveSendEventArgs, receiveSendToken, remainingBytesToProcess);

if (incomingTcpMessageIsReady == true)
{
   ...
   AddTokenToList(receiveSendToken);
}




private void AddTokenToList(DataHoldingUserToken theUserToken)
        {
            lock (this.lockerForList)
            {
                DataHoldingUserToken uTokenHere;
                for (int countT = 0; countT < Program.listOfTokens.Count; countT++)
                {
                    uTokenHere = (DataHoldingUserToken) Program.listOfTokens[countT];
                    if (uTokenHere.unitID == theUserToken.unitID)
                    {
                        //remove the previous socket

                    }
                    else {
                        Program.listOfTokens.Add(theUserToken);
                    }
                }

            }
        }

1 个答案:

答案 0 :(得分:1)

TCP是面向连接的。当您的对等体正常关闭连接时,意味着客户端不会崩溃或拔出插头,他将在套接字上关闭。服务器通过0字节套接字的一端接收检测到此关闭。这意味着它也是时候关闭套接字的结尾了。

使用TCP时,如果没有进行消息交换,则无法检测到TCP连接是否中断。检测连接消失的唯一方法是使用keep alive,或者在每个时间间隔从服务器向客户端发送一条简单的消息,有效地实现自己保持活动状态。如果客户端在几次重新传输后没有响应,您可以关闭连接。