C#在UDP上收到的数据总是无用的

时间:2013-09-28 06:02:21

标签: c# sockets udp

这是我的问题;我正在尝试将UDP服务器 - 客户端交互作为测试。我希望客户端将数据发送到服务器,如果服务器与服务器保持的数据匹配,则会发送回复。简单吧?这是一些代码:

客户端发送/接收代码:

void TestUDP()
    {
        Socket sock_addr = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint srver_endpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 36);
        string numbers = "1.2.3.4";
        byte[] srver_req = Encoding.UTF8.GetBytes("TEST|" + numbers);

        sock_addr.SendTo(srver_req, srver_endpoint);

        EndPoint ref_endpoint = (EndPoint)srver_endpoint;
        byte[] req_reply = new byte[1000];
        sock_addr.ReceiveFrom(req_reply, ref ref_endpoint);

        string reply = Encoding.UTF8.GetString(req_reply).Trim();

        string[] s_str = reply.Split('|');

        if (s_str[0] == "HEY")
        {
            MessageBox.Show("HEY");
        }
        else
        {
            MessageBox.Show("NO");
        }
    }

现在有些服务器代码:

public void start()
    {
        udp_sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        udp_sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);

        udp_thr = new Thread(udpListen);
        udp_thr.Start();
    }

    void udpListen()
    {
        byte[] data = new byte[1024];
        IPEndPoint ip = new IPEndPoint(IPAddress.Any, 36);

        udp_sock.Bind(ip);

        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        EndPoint Remote = (EndPoint)(sender);

        while (true)
        {
            udp_sock.ReceiveFrom(data, ref Remote);

            Parse(data, Remote);
        }
    }

    void Parse(byte[] data, EndPoint Remote)
    {
        string decData = Encoding.UTF8.GetString(data).Trim();
        string[] s_str = decData.Split('|');
        byte[] sendBuffer = new byte[] { };

        switch (s_str[0])
        {
            case "TEST":
                string data1 = s_str[1];

                if (data1 == "1.2.3.4")
                {
                    sendBuffer = Encoding.UTF8.GetBytes("HEY|");
                }
                else if(data1 != "1.2.3.4")
                {
                    sendBuffer = Encoding.UTF8.GetBytes("NO|");
                }

                udp_sock.SendTo(sendBuffer, Remote);
                break;
        }
    }

现在的问题是,它总是说“不”,我不明白为什么。对我来说这看起来应该有用,我做错了什么? 我已将此套接字置于Broadcast上,因为我也想用此处理广播请求。这是一个问题吗?

1 个答案:

答案 0 :(得分:3)

首先,您应该添加诊断信息以打印实际数据,而不仅仅是知道它是“正确”或“错误”。

接下来,实际问题是你忽略了udp_sock.ReceiveFrom的结果。这将告诉你实际收到了多少字节。目前,您总是将所有1024个字节转换为字符串...这意味着您可能会收到您尚未收到的尾随数据。仅仅使用Trim()并不是解决这个问题的好方法。 Trim()不会将U + 0000视为空格,即使它 它仍然不是一个合适的方法 - 除了其他任何东西之外,你将在以后重用相同的缓冲区,所以如果你收到一条长信息,然后是一条较短的信息,你最终会得到一个混合信息。

你想:

// TODO: Fix your variable names, which are inconsistent non-idiomatic
int bytesRead = udp_sock.ReceiveFrom(data, ref Remote);
Parse(data, bytesRead, Remote);

并将Parse更改为:

void Parse(byte[] data, int bytesRead, EndPoint remote)
{
    string text = Encoding.UTF8.GetString(data, 0, bytesRead);
    ...
}

您需要在客户端和服务器上执行此操作。

另外,鉴于if / else的第一个分支检查data1 是否“1.2.3.4”,您不需要然后检查不是