我需要帮助找到消息队列的最佳和最快的数据结构。
架构如下:客户端从外部C ++服务器获取消息(不能查找它的代码)。消息的格式为msg.length + data。
在旧代码中,使用TcpClient类进行连接,将MemoryStream用作队列。客户端从此TCPClient读取数据并将其复制到流中。如果在这个读取客户端读取整个消息,它正在另一个线程中处理,一切都很完美。如果有部分消息或2条消息在一起,代码就会变得非常混乱。
我强烈感觉有可能轻松编写代码。让我烦恼的是" play"在MemoryStream中使用指针,并且需要以某种方式从中删除旧数据。
答案 0 :(得分:4)
您可以使用Queue类;它就像一个FIFO,先进先出。您需要两个线程(至少)一个来读取来自套接字的消息并入队到FIFO,另一个线程将消息出列并处理它们。您还需要使用互斥锁以防止同时访问队列。这是代码:
class MessagePacket
{
private byte[] data;
private int length;
public MessagePacket(int len, byte[] aData)
{
this.length = len;
data = new byte[len];
Array.Copy(aData, data, len);
}
public int Length()
{
return this.length;
}
public byte[] Data()
{
return this.data;
}
}
static Queue<MessagePacket> MsgQueue = new Queue<MessagePacket>();
static Mutex mutQueue = new Mutex();
/// <summary>
/// This thread read the message from the sever and put them in the queue.
/// </summary>
static void readSocket()
{
byte[] dataSize = new byte[4];
while (true/*or ApplicationIsActive*/)
{
try
{
// it's assumed that data is a 32bit integer in network byte order
if (ClientSocket.Receive(dataSize, 4, SocketFlags.None) != 4)
{
return;
}
int size = BitConverter.ToInt32(dataSize, 0);
size = IPAddress.NetworkToHostOrder(size);
byte[] buffer = new byte[size];
int offset = 0;
while (size > 0)
{
int ret = ClientSocket.Receive(buffer, offset, size, SocketFlags.None);
if (ret <= 0)
{
// Socket has been closed or there is an error, quit
return;
}
size -= ret;
offset += ret;
}
mutQueue.WaitOne();
try { MsgQueue.Enqueue(new MessagePacket(size, buffer)); }
finally { mutQueue.ReleaseMutex(); }
}
catch
{
return;
}
}
}
/// <summary>
/// This thread processes the messages in the queue.
/// </summary>
static void processMessages()
{
while (true/*or ApplicationIsActive*/)
{
if (MsgQueue.Count > 0)
{
MessagePacket msg;
mutQueue.WaitOne();
try { msg = MsgQueue.Dequeue(); }
finally { mutQueue.ReleaseMutex(); }
// Process the message: msg
}
else Thread.Sleep(50);
}
}