首页 文章

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

提问于
浏览
-3

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

我正在尝试从服务器向客户端发送确认消息 . 我尝试将C#客户端代码与现有的C#Server代码合并,但一旦服务器收到第一条消息 System.ObjectDisposedException ,它就会崩溃 . 我删除并重新开始"See edited if you want" . 现在,我成功发送到服务器但没有收到任何内容,Java客户端也没有显示任何内容 . 我知道我可以(或者应该)使用相同的套接字发送回客户端 . Where is my mistake? 请和谢谢 .

  • 我试过将整个 NetworkThread 放在 OnTouchListener

  • 我尝试将 SendUdpMessage() 分解为两个,一个发送,一个接收

  • 我尝试了下面的答案

而我仍然无法使它工作:(

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 + "\n");

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

    }
}

Java客户端:一个按钮调用一个函数来发送UDP消息,并将响应分配给一个全局变量,然后我尝试通过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() 
    }       
}

2 回答

  • 1

    网络代码工作,问题是你不等待响应,即 SendUdpMsg 方法不能立即返回响应,它应该由后台线程推送 . 例如 :

    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提供了一些工具,如HandlerAsyncTask

  • 0

    所以我把它添加到我的 SendUdpMsg()

    runOnUiThread(new Runnable() {
        @Override
        public void run()
               {
                     final TextView TextOne = (TextView) findViewById(R.id.StatusText);
                     TextOne.setText(Response);
               }
    });`
    

    最后它奏效了!在按钮上单击我成功发送 message 并接收 Response .

    Mission: 我想点击我的手机,开始从笔记本电脑_2625335的屏幕直播视频 .

    Request: 我对这种双向沟通的态度是好的吗?如果没有什么是最好的?

相关问题