为什么我的 UDP 客户端/服务器数据报没有进行双向通信?
我在两个应用程序之间建立了一个简单的 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 theOnTouchListener
- 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
相关文章