0

大家好,我有这个问题,我被困住了,所以任何帮助都将不胜感激

我必须构建一个套接字聊天(客户端服务器)模块,我已经完成了几乎 80% 的工作,但现在我被卡住了,场景是我有一个服务器应用程序,如果说 4 个客户端连接到服务器,客户端现在连接到它他们每个人都可以相互通信,一个客户端将发送消息,服务器将接收该消息并将其传递,这工作得很好,但是当 2 个或更多客户端同时向第三个客户端发送消息时,我可以没有收到一条消息并且客户端断开连接我知道我必须建立一个队列结构但我没有成功这里是我的代码结构

StartReceive(SocketAsyncEventArgs) ->

首先我调用这个方法开始监听传入的消息

当我收到一条消息时,我会检查它是完成同步还是异步

在此之后,有一个 io 完成的侦听器,每次完成一个接收操作时都会调用它,并且在该 io 完成的方法中,我确实调用了用于处理接收到的块的 processReceive 方法,所以最后我的代码结构是这样的

StartReceive-> IO Completed -> ProcessReceive

我已经设计了结构,以便每个客户端在服务器端都有一个接收 SOCKETASYNCEVENTAGRS 对象和一个发送 SOCKETASYNCEVENTAGRS,我确实为此维护了一个池

所以每个客户端都通过自己的 SOCKETASYNCEVENTAGRS 对象接收和发送数据

我想要一个场景,如果两个或多个客户端向第三个客户端发送消息,而不是第三个客户端不应该同时接收所有消息,而是它应该有一个队列结构,它应该一次接收一条消息,并且发送操作相同

这是我的一些代码

  private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
    {
        DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
        receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);                    
        bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
        if (!willRaiseEvent)
        {

            ProcessReceive(receiveSendEventArgs);                
        }            
    }

这是 IO 完成

 void IO_Completed(object sender, SocketAsyncEventArgs e)
    {
        DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)e.UserToken;
        switch (e.LastOperation)
        {
            case SocketAsyncOperation.Receive:                
                ProcessReceive(e);
                break;

            default:
        }
    }

这是我的 StartReceive 与队列实现但它不工作

 Queue rec = new Queue();
    bool IsExecuted = true;
    private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
    {
        if (IsExecuted)
        {
            DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
            rec.Enqueue(receiveSendToken);
        }
        try
        {
            receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);
            bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
            if (!willRaiseEvent)
            {

                ProcessReceive(receiveSendEventArgs);
            }
            rec.Dequeue();
            IsExecuted = true;
        }
        catch
        {
            IsExecuted = false;
            StartReceive(receiveSendEventArgs);
        }
    }

寻找体面的帮助或一些好的方向

4

1 回答 1

1

我不确定这是否是您问题的根本原因,但在我看来,您DataHoldingUserToken有时会用完,因为您从未对出列的对象做任何事情,因此您将其丢弃。

另请注意,建议对非平凡对象使用 Queue 类的通用形式。那将是System.Collections.Generic.Queue<DataHoldingUserToken>

于 2013-08-19T10:14:53.823 回答