解码时c#参数中的TCP / IP套接字为null

时间:2016-01-14 15:00:13

标签: c# encoding udp decoding

我认为帮助解决问题最简单的方法就是发布项目here。但这不会起作用。

以下是我认为出错的部分:

public class ItemQuoteDecoderText : ItemQuoteDecoder
{
    //Character encoding
    public Encoding encoding;

    public ItemQuoteDecoderText() : this(ItemQuoteTextConst.DEFAULT_CHAR_ENC) { }

    public ItemQuoteDecoderText(string encodingDesc)
    {
        encoding = Encoding.GetEncoding(encodingDesc);
    }

    public ItemQuote decode(Stream wire)
    {
        string itemNo, description, quant, price, flags;

        byte[] space = encoding.GetBytes(" ");
        byte[] newline = encoding.GetBytes("\n");

        itemNo = encoding.GetString(ItemQuoteFramer.nextToken(wire, space));
        description = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
        quant = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
        price = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
        flags = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));

        return new ItemQuote(Int64.Parse(itemNo),
                                description,
                                Int32.Parse(quant),
                                Int32.Parse(price),
                                (flags.IndexOf('d') != -1),
                                (flags.IndexOf('s') != -1));
    }

    public ItemQuote decode(byte[] packet)
    {
        Stream payload = new MemoryStream(packet, 0, packet.Length, false);
        return decode(payload);
    }
}

在解码器处,输入流被解码以形成可读取结果。不幸的是,错误发生在:

price = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));

显示消息:

An exception of type 'System.ArgumentNullException' occurred in mscorlib.dll but was not handled in user code

Additional information: Array cannot be null.

ItemQuoteFramer:

    public class ItemQuoteFramer
{
    public static byte[] nextToken(Stream input, byte[] delimiter)
    {
        int nextByte;

        //If the stream has already ended, return null
        if ((nextByte = input.ReadByte()) == -1)
            return null;

        MemoryStream tokenBuffer = new MemoryStream();
        do
        {
            tokenBuffer.WriteByte((byte)nextByte);
            byte[] currentToken = tokenBuffer.ToArray();
            if (endsWith(currentToken, delimiter))
            {
                int tokenLength = currentToken.Length - delimiter.Length;
                byte[] token = new byte[tokenLength];
                Array.Copy(currentToken, 0, token, 0, tokenLength);

                return token;
            }
        }
        while ((nextByte = input.ReadByte()) != -1);

        return tokenBuffer.ToArray();
    }

    static bool endsWith(byte[] value, byte[] suffix)
    {
        if (value.Length < suffix.Length)
            return false;

        for (int offset = 1; offset <= suffix.Length; offset++)
            if (value[value.Length - offset] != suffix[suffix.Length - offset])
                return false;

        return true;
    }
}

在ItemQuoteDecoderText中填充变量“quant”后,将跳过它的分隔符。这留下了发送数据包的最后一部分:“1000 12999 d”作为一个整体在“quant”中,并将为最后两个(“价格”和“标志”)变量返回null。

    public class SendUdp
{
    public SendUdp(string[] args)
    {
        SendUdpMethod(args);
    }

    void SendUdpMethod(string[] args)
    {
        //Check for correct amount of arguments
        if ((args.Length < 2) || (args.Length > 3))
            throw new ArgumentException("Parameters: <Destination> <Port> [<Encoding>]");

        string server = args[0];
        int destPort = Int32.Parse(args[1]);

        //Make an item to quote
        ItemQuote quote = new ItemQuote(12345678909876554L, "5mm Super Widgets", 1000, 12999, true, false);

        UdpClient client = new UdpClient();

        ItemQuoteEncoder encoder = ((args.Length == 3) ? new ItemQuoteEncoderText(args[2]) : new ItemQuoteEncoderText());
        byte[] codedQuote = encoder.encode(quote);

        client.Send(codedQuote, codedQuote.Length, server, destPort);
        client.Close();
    }
}

这是将处理数据包接收方式的代码:

    public class ReceiveUdp
{
    public ReceiveUdp(string[] args)
    {
        ReceiveUdpMethod(args);
    }

    void ReceiveUdpMethod(string[] args)
    {
        //Check for correct amount of arguments
        if ((args.Length < 1) || (args.Length > 2))
            throw new ArgumentException("Parameters: <Port> [<Encoding>]");

        int port = Int32.Parse(args[0]);
        UdpClient client = new UdpClient(port);

        byte[] packet = new byte[ItemQuoteTextConst.MAX_WIRE_LENGTH];
        IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, port);

        packet = client.Receive(ref remoteIPEndPoint);
        ItemQuoteDecoderText decoder = ((args.Length == 2) ? new ItemQuoteDecoderText(args[1]) : new ItemQuoteDecoderText());

        ItemQuote quote = decoder.decode(packet);
        Console.WriteLine(quote);

        client.Close();
    }
}

ItemQuoteFramer 喜欢跳过分隔符,我认为这就是出错的地方。但我不知道该怎么做。有人愿意花时间帮助我搞清楚吗?

非常感谢,
Farcrada

1 个答案:

答案 0 :(得分:0)

答案在于分隔符的给定方式。变量“quant”保持(在出错时)以下内容:“1000 12999 d”。

如果你看一下通过哪个分隔符,它会给出:“newline”。如果我们将其更改为:“space”,我们就会解决问题。

澄清, ItemQuoteDecoderText 中的以下内容:

    itemNo = encoding.GetString(ItemQuoteFramer.nextToken(wire, space));
    description = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
    quant = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
    price = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
    flags = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));

应该成为:

    itemNo = encoding.GetString(ItemQuoteFramer.nextToken(wire, space));
    description = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));
    quant = encoding.GetString(ItemQuoteFramer.nextToken(wire, space));
    price = encoding.GetString(ItemQuoteFramer.nextToken(wire, space));
    flags = encoding.GetString(ItemQuoteFramer.nextToken(wire, newline));

我要感谢所有花时间看一看的人。

非常感谢,
Farcrada