为何我的UDP客户端/服务器的数据报不工作的双向通信? [英] Why my UDP client/server datagram is not operating the two-way communication?

查看:205
本文介绍了为何我的UDP客户端/服务器的数据报不工作的双向通信?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我试图从服务器发送确认信息返回给客户端。我试图合并C#的客户端代码与现有的C#Server代码,但一旦服务器接收到它的第一个消息,它崩溃 System.ObjectDisposedException 。我删除,并开始从头再来看,如果你想编辑。现在,我成功地发送到服务器,但是未收到任何没有东西显示在Java的客户端。我知道我可以(或者应该)使用相同的套接字来发送回客户端。 哪里是我错了吗?请和感谢。




  • 我试图把整个 NetworkThread OnTouchListener

  • 我试图打破 SendUdpMessage()一分为二,一个用于发送,一个用于接收

  • 我想下面的答案



和我仍然不能使它发挥作用:(



C#服务器端:

  //这个类负责在PC上运行的服务器端的
类UdpServer
{
静态无效的主要(字串[] args)
{
字节[]数据=新的字节[1024];
UdpClient的ServerSocket =新的UdpClient(15000);
INT I = 0;

,而(真)
{
Console.WriteLine(等待一个UDP客户端...);
IPEndPoint发件人=新IPEndPoint(IPAddress.Any,0);
数据= ServerSocket的。接收(REF发送者);

串StringData是= Encoding.ASCII.GetString(数据,0,data.Length);
Console.WriteLine(+ sender.Address从响应);
Console.WriteLine(消息+ I ++ +:+ StringData是+\\\
);

//我在这里发回
字节[]数据2 = Encoding.ASCII.GetBytes(回应);
serverSocket.Send(数据2,8,发送者);
}

}
}



Java客户端方:
A键调用一个函数来发送一个UDP消息,并指定响应转换成一个全局变量,然后我试着通过一个TextBox



显示在屏幕上

 公共类MainActivity扩展AppCompatActivity {

字符串消息;
字符串响应;

@覆盖
保护无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main);

//按钮宣言
最终的TextView TextOne =(的TextView)findViewById(R.id.StatusText);
键LftBtn =(按钮)findViewById(R.id.LeftButton);
// ...
//此处其它代码(按钮声明和事件处理程序
// ...

//左键点击
LftBtn.setOnTouchListener(
新Button.OnTouchListener(){
公共布尔onTouch(视图v,MotionEvent事件){
如果(event.getAction()== MotionEvent.ACTION_DOWN){
//按下按钮
TextOne.setText(左);
=消息左;
SendUdpMsg(消息);
TextOne.setText(响应);
返回真;
}否则如果(event.getAction()== MotionEvent.ACTION_UP){
//按键释放什么也不做
返回真;
}
返回FALSE;
} // onTouch
}); // setOnTouchListener
}

//这个函数是负责发送一个UDP包,一个硬编码下面的IP。返回任何内容并接受一个字符串(消息)作为参数。
公共无效SendUdpMsg(最终弦乐味精)
{
螺纹networkThread =新主题(){

//在Android的$ B $无本地主机127.0.0.1 b字符串主机=192.168.200.3; //我的实际IP
INT端口= 15000;
DatagramSocket的DSOCKET = NULL;
字符串响应=1;

公共无效的run(){
尝试{
//获取指定的主机
InetAddress类地址= InetAddress.getByName(主机)的互联网地址;

//包一包
DatagramPacket类包=新的DatagramPacket(
msg.getBytes(),
msg.length(),
地址,端口);

//创建一个数据报套接字,通过它发送数据包,将其关闭。
DSOCKET =新的DatagramSocket();
dsocket.send(包);

//在这里,我收到的回应?
字节[]缓冲区=新的字节[1024];
DatagramPacket类packet2 =新的DatagramPacket(缓冲,buffer.length);
dsocket.receive(packet2);
响应=新字符串(缓冲液,0,packet2.getLength());
runOnUiThread(新的Runnable(){
@覆盖
公共无效的run()
{
//我不能用这个,因为TextOne是在一个局部变量上述功能$​​ b $ b //TextOne.setText(Response);
}
});
dsocket.close();
}赶上(例外五){
e.printStackTrace();
} //抓
} //运行
}; // Networkthread
networkThread.start(); // networkThread.start()
}
}


解决方案

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

  dsocket.receive(packet2); 
响应=新字符串(缓冲液,0,packet2.getLength());

//我们收到的响应
//但由于是在后台线程运行时,我们不能碰UI
runOnUiThread(新的Runnable(){$ B $
}); b @覆盖
公共无效的run(){
//这是在主(UI)线程
TextOne.setText(响应)执行};

dsocket.close();



由于必须在后台线程工作,并处理在主线程的结果是一个常见的​​模式。 Android提供如处理器或的 AsyncTask的


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.

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.

  • 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# Server Side:

// 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 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() 
    }       
}

解决方案

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();

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

这篇关于为何我的UDP客户端/服务器的数据报不工作的双向通信?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆