我在两个应用程序之间建立了一个简单的UDP客户端/服务器数据报:Android-Java- Client和Windows-C#-Server。这是我第一次使用Java编程和Android应用程序,因此解决方案可能很明显。因此,我成功地从客户端向服务器发送了一个数据包。但是,我无法从服务器发送回客户端。
我正在尝试将确认消息从服务器发送回客户端。我尝试将C#客户端代码与现有的C#服务器代码合并,但是一旦服务器收到第一条消息,它就会崩溃System.ObjectDisposedException。我删除并重新开始“如果需要,请编辑”。现在,我已成功发送到服务器,但是没有收到任何消息,并且Java客户端上也没有任何显示。我知道我可以(也许应该)使用相同的套接字发送回客户端。 我的错误在哪里? 请和谢谢。
System.ObjectDisposedException
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() } }
网络代码有效,问题在于您没有在等待响应,即该SendUdpMsg方法无法立即返回响应,应该由后台线程推送该响应。例如 :
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提供了一些工具,例如Handler或AsyncTask