套接字队列问题
本文关键字:问题 队列 套接字 | 更新日期: 2023-09-27 18:25:52
你好,我有这个问题,我一直在处理它,所以任何帮助都将非常感谢
我必须建立一个套接字聊天(客户端-服务器)模块,我已经完成了几乎80%的工作,但现在我陷入了困境,场景是我有一个服务器应用程序,客户端现在连接到它,如果假设4个客户端连接到服务器,每个客户端都可以相互通信,一个客户端将发送消息,服务器将接收该消息并传递,这很好,但当两个或多个客户端同时向第三个客户端发送消息时,我无法获得一条消息,并且客户端断开连接,我知道我必须建立一个队列结构,但我在这里没有成功这是我的代码结构
StartReceive(SocketAsyncEventArgs) ->
首先,我调用这个方法来开始侦听传入消息
当我收到一条消息时,我会检查它是否完成了同步或异步
在这之后,有一个io完成的监听器,每次完成一个接收操作时都会调用它,在这个io完成的方法中,我调用processReceive方法,该方法用于处理接收到的块所以最后我的代码结构是这样的
StartReceive-> IO Completed -> ProcessReceive
我设计的结构使每个客户都有一个Receive SOCKETASYNCEVENTAGRS对象和服务器端的SendSOCKETASYNCEVENTAGRS,我为这个维护了一个池
因此每个客户端都通过自己的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,但它不工作
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);
}
}
寻找一个体面的帮助或一些好的方向
我不确定这是否是问题的根本原因,但在我看来,DataHoldingUserToken
在某个时候已经用完了,因为你从来没有对退出队列的对象做过任何事情,所以你要把它扔掉。
还要注意,对于非平凡对象,建议使用Queue类的通用形式。那将是System.Collections.Generic.Queue<DataHoldingUserToken>
。