简体   繁体   中英

C# Data received on UDP is always useless

Here's my problem; I'm trying to make a UDP server - client interaction as a test. I want the client to send data to the server, and if the server matches data the server holds, it sends a reply. Simple, right? Here's some code:

Client send/receive code:

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");
        }
    }

Now some server code:

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;
        }
    }

Now the issue is, it ALWAYS says "NO", I have no idea why. To me this looks like it should work, what am I doing wrong?? I've put this socket onto Broadcast, because I'd also like to handle Broadcast requests with this too. Is that a problem?

Firstly, you should add diagnostics to print out the actual data rather than just knowing that it's "right" or "wrong".

Next, the actual problem is that you're ignoring the result of udp_sock.ReceiveFrom . That will tell you how many bytes have actually been received. Currently, you're always converting all 1024 bytes into a string... which means you're likely to have trailing data which you haven't just received. Just using Trim() isn't a good way of countering that. Trim() doesn't count U+0000 as whitespace, and even if it did it still wouldn't be an appropriate approach - aside from anything else, you're reusing the same buffer later, so if you received a long message and then a shorter one, you'd end up with a mixture.

You want:

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

and change Parse to:

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

You need to do that on both the client and the server.

Also, given that the first branch of the if / else checks whether data1 is "1.2.3.4", you don't need to then check that it isn't .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM