为什么MSMQ不会发送空格字符?

时间:2010-05-24 18:33:05

标签: c# xml-serialization character-encoding msmq tostring

我正在探索MSMQ服务,我编写了一个简单的控制台客户端 - 服务器应用程序,它将每个客户端的击键发送到服务器。每当遇到控制字符(DELESCINS等)时,服务器都会引发错误。但是,每当我键入空格字符时,服务器都会收到数据包,但不会抛出错误,也不会显示空格。

服务器

namespace QIM
{
    class Program
    {
        const string QUEUE = @".\Private$\qim";
        static MessageQueue _mq;
        static readonly object _mqLock = new object();
        static XmlSerializer xs;

        static void Main(string[] args)
        {
            lock (_mqLock)
            {
                if (!MessageQueue.Exists(QUEUE))
                    _mq = MessageQueue.Create(QUEUE);
                else
                    _mq = new MessageQueue(QUEUE);
            }
            xs = new XmlSerializer(typeof(string));
            _mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
            while (Console.ReadKey().Key != ConsoleKey.Escape) { }
        }

        static void OnReceive(IAsyncResult result)
        {
            Message msg;
            lock (_mqLock)
            {
                try
                {
                    msg = _mq.EndReceive(result);
                    Console.Write(".");
                    Console.Write(xs.Deserialize(msg.BodyStream));
                }
                catch (Exception ex)
                {
                    Console.Write(ex);
                }
            }
            _mq.BeginReceive(new TimeSpan(0, 1, 0), new object(), OnReceive);
        }
    }
}

客户端:

namespace QIM_Client
{
    class Program
    {
        const string QUEUE = @".\Private$\qim";
        static MessageQueue _mq;

        static void Main(string[] args)
        {
            if (!MessageQueue.Exists(QUEUE))
                _mq = MessageQueue.Create(QUEUE);
            else
                _mq = new MessageQueue(QUEUE);
            ConsoleKeyInfo key = new ConsoleKeyInfo();
            while (key.Key != ConsoleKey.Escape)
            {
                key = Console.ReadKey();
                _mq.Send(key.KeyChar.ToString());
            }
        }
    }
}

客户输入:

  

测试,测试......

服务器输出:

  

.T.e.s.t.i.n.g。,.. T.e.s.t.i.n.g ......

您会注意到空格字符发送消息,但不显示该字符。

2 个答案:

答案 0 :(得分:5)

您的问题不在于MSMQ,而在于XmlSerializer类。参见:

var key = Console.ReadKey();

XmlSerializer s = new XmlSerializer(typeof(string));

using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
    s.Serialize(ms, key.KeyChar.ToString());

    ms.Position = 0;

    var foo = (string)s.Deserialize(ms);
}

如果您在控制台中输入空格,您会看到key.KeyChar.ToString()产生" ",但foo等于""。由于XmlReader的默认实现,XmlSerializer类认为只有空格的字符串为空;如果字符串包含任何其他字符,则保留前导和尾随空格。空白 进行序列化,但反序列化会将其变为空字符串。

请改用:

Console.Write(
    s.Deserialize(System.Xml.XmlReader.Create(msg.BodyStream, 
                                          new System.Xml.XmlReaderSettings() 
                                          { 
                                              IgnoreWhitespace = false 
                                          })));

答案 1 :(得分:3)

@Adam的答案是对的。最简单的解决方案是使用BinaryMessageFormatter(无论如何都会导致消息略小)。

在客户端和服务器中初始化消息队列对象后,请明确设置格式化程序:

_mq.Formatter = new BinaryMessageFormatter();

然后在服务器中,不要试图直接搞乱BodyStream。而只是使用Body(已经被格式化程序反序列化):

Console.Write(".");
Console.Write(msg.Body);