为什么我的 UDP 客户端/服务器数据报没有进行双向通信?

2022-01-22 00:00:00 sockets udp c# android java

我在两个应用程序之间建立了一个简单的 UDP 客户端/服务器数据报:Android-Java-Client 和 Windows-C#-Server.这是我的第一个 Java 编程和 Android 应用程序,因此解决方案可能很明显.所以我成功地从客户端向服务器发送了一个数据包.但是,我无法从服务器发送回客户端.

I set up a simple UDP client/server datagram between two applications: Android-Java-Client and Windows-C#-Server. This is my first ever Java programming and Android applications so the solution might be obvious. So I succeeded in sending a packet from the client to the server. However, I couldn't send back from the server to the client.

我正在尝试将确认消息从服务器发送回客户端.我尝试将 C# 客户端代码与现有的 C# 服务器代码合并,但是一旦服务器收到它的第一条消息 System.ObjectDisposedException,它就会崩溃.我删除并重新开始如果需要,请参阅已编辑".现在,我成功发送到服务器,但没有收到任何内容,Java 客户端上也没有显示任何内容.我知道我可以(或者应该)使用相同的套接字发送回客户端.我的错误在哪里?请,谢谢.

I am trying to send a confirmation message from the server back to the client. I tried merging C# Client code with the existing C# Server code but it crashes once the server receives its first message System.ObjectDisposedException. I deleted and started all over again "See edited if you want". Now, I send successfully to the server but nothing is received and nothing gets displayed on the Java Client Side. I know that I can (or maybe should) use the same socket to send back to the client. Where is my mistake? Please and Thanks.

  • 我尝试将整个 NetworkThread 放入 OnTouchListener
  • 我尝试将 SendUdpMessage() 分解为两部分,一是发送,一是接收
  • 我尝试了以下答案
  • I tried putting the whole NetworkThread in the OnTouchListener
  • I tried breaking down SendUdpMessage() into two, one to send and one to receive
  • I tried the below answer

我仍然无法让它工作:(

And I still can't make it work :(

C# 服务器端:

// This class is responsible of running the server side on the PC. 
class UdpServer
{
    static void Main(string[] args)
    {
        byte[] data = new byte[1024];
        UdpClient serverSocket = new UdpClient(15000);
        int i = 0;

        while (true)
        {
            Console.WriteLine("Waiting for a UDP client...");
            IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
            data = serverSocket.Receive(ref sender);

            string stringData = Encoding.ASCII.GetString(data, 0, data.Length);
            Console.WriteLine("Response from " + sender.Address);
            Console.WriteLine("Message " + i++ + ": " + stringData + "
");

            // Here I am sending back
            byte[] data2 = Encoding.ASCII.GetBytes("Response");
            serverSocket.Send(data2, 8, sender);
        }

    }
}

Java 客户端:一个按钮调用一个函数来发送一条 UDP 消息,并将响应分配给一个全局变量,然后我尝试通过 TextBox 在屏幕上显示该变量

Java Client Side: A button calls a function to send a UDP message, and assign the response into a global variable which then I try to display on the screen via a TextBox

    public class MainActivity extends AppCompatActivity {

    String message;
    String Response;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Button Declaration
        final TextView TextOne = (TextView) findViewById(R.id.StatusText);
        Button LftBtn = (Button) findViewById(R.id.LeftButton);
        // ...
        // other code here (button declaration and event handlers
        // ...

        // Left Button Click
        LftBtn.setOnTouchListener(
                new Button.OnTouchListener() {
                    public boolean onTouch(View v, MotionEvent event) {
                        if (event.getAction() == MotionEvent.ACTION_DOWN) {
                            //Button pressed
                            TextOne.setText("Left");
                            message = "Left";
                            SendUdpMsg(message);
                            TextOne.setText(Response);
                            return true;
                        } else if (event.getAction() == MotionEvent.ACTION_UP) {
                            //Button released do nothing
                            return true;
                        }
                        return false;
                    }//onTouch
                });//setOnTouchListener
    }

    // This function is responsible for sending a udp packet to a hardCoded IP below. Returns nothing and takes a string(the message) as a parameter.
    public void SendUdpMsg(final String msg)
    {
        Thread networkThread = new Thread() {

            // No local Host 127.0.0.1 in Android
            String host = "192.168.200.3"; // my actual IP
            int port = 15000;
            DatagramSocket dsocket = null;
            String Response = "1";

            public void run() {
                try {
                    // Get the Internet address of the specified host
                    InetAddress address = InetAddress.getByName(host);

                    // wrap a packet
                    DatagramPacket packet = new DatagramPacket(
                            msg.getBytes(),
                            msg.length(),
                            address, port);

                    // Create a datagram socket, send the packet through it, close it.
                    dsocket = new DatagramSocket();
                    dsocket.send(packet);

                    // Here, I am receiving the response?
                    byte[] buffer = new byte[1024];
                    DatagramPacket packet2 = new DatagramPacket(buffer, buffer.length);
                    dsocket.receive(packet2);
                    Response = new String(buffer, 0, packet2.getLength());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run()
                        {
                            // I can't use this since TextOne is a local variable in the above function
                            //TextOne.setText(Response);
                        }
                    });
                    dsocket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }//catch
            }//run
        };// Networkthread
        networkThread.start();//networkThread.start() 
    }       
}

推荐答案

网络代码正常,问题是你没有等待响应,即SendUdpMsg方法无法返回响应立即,它应该由后台线程推送.例如:

The network code works, the problem is that your are not waiting for the response, i.e. the SendUdpMsg method can not return the response immediately, it should be pushed by the background thread. For example :

dsocket.receive(packet2);
Response = new String(buffer, 0, packet2.getLength());

// we received the response
// but since we are running on a background thread, we can not touch the UI
runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // this is executed on the main (UI) thread
        TextOne.setText(Response);                        }
});

dsocket.close();

必须在后台线程上工作并在主线程上处理结果是一种常见的模式.Android 提供了一些工具,例如 Handler 或 AsyncTask

Having to work on a background thread and handle the results on the main thread is a common pattern. Android provides a few tools like Handler or AsyncTask

相关文章