在UDP Socket java android上发送和接收数据
我能够通过 UDP 套接字正确发送我的数据,但是当我收到数据时,它一直在等待接收命令,我不知道是什么原因造成的.请看下面我的代码.
I am able to properly send my data through UDP socket , but when I receive data it keeps on waiting at receive command I don't know what is causing this. Please have a look at my code below.
我能够在服务器端从 android 设备正确接收数据,但是当我将数据从服务器端发送到 android 设备时,它没有接收到.但是当我将数据从服务器发送到任何其他客户端(例如 PC 应用程序)时,它会正确接收并显示数据.
I am able to properly receive data at server side from android device, but when I send data from server side to android device it doesn't receive. but when I send data from server to any other client e.g PC application it receive and displays data properly.
class Task implements Runnable {
@Override
public void run() {
try {
String messageStr = "feed";
int server_port = 8888;
InetAddress local = InetAddress.getByName("10.0.2.2");
int msg_length = messageStr.length();
byte[] message = messageStr.getBytes();
DatagramSocket s = new DatagramSocket();
//
DatagramPacket p = new DatagramPacket(message, msg_length, local, server_port);
s.send(p);//properly able to send data. i receive data to server
for (int i = 0; i <= 20; i++) {
final int value = i;
message = new byte[30000];
p = new DatagramPacket(message,message.length );
s.receive(p); //keeps on waiting here but i am sending data back from server, but it never receives
final byte[] data = p.getData();;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
progressBar.setProgress(value);
imageView.setImageBitmap(BitmapFactory.decodeByteArray(data,0,data.length));
}
});
}
}
catch(Exception ex)
{
}
}
}
推荐答案
Eclipse 中的文档:
Documentation in Eclipse:
从这个套接字接收一个数据包并将其存储在参数包中.pack 的所有字段都必须根据接收到的数据进行设置.如果接收到的数据长于被截断的数据包缓冲区大小.此方法阻塞,直到收到数据包或超时过期了.
Receives a packet from this socket and stores it in the argument pack. All fields of pack must be set according to the data received. If the received data is longer than the packet buffer size it is truncated. This method blocks until a packet is received or a timeout has expired.
s.receive(p);
"命令阻塞线程,直到它接收到数据或用 setSoTimeout(timeout) 设置的超时结束.
The "s.receive(p);
" command blocks the thread until it receices data or the timeout set with setSoTimeout(timeout) is over.
我已经做了 2 节课来进行交流.第一个 UDP 服务器:
I have made 2 classes to make my communication happen. First UDP-Server:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Build;
public class UDP_Server
{
private AsyncTask<Void, Void, Void> async;
private boolean Server_aktiv = true;
@SuppressLint("NewApi")
public void runUdpServer()
{
async = new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
byte[] lMsg = new byte[4096];
DatagramPacket dp = new DatagramPacket(lMsg, lMsg.length);
DatagramSocket ds = null;
try
{
ds = new DatagramSocket(Main.SERVER_PORT);
while(Server_aktiv)
{
ds.receive(dp);
Intent i = new Intent();
i.setAction(Main.MESSAGE_RECEIVED);
i.putExtra(Main.MESSAGE_STRING, new String(lMsg, 0, dp.getLength()));
Main.MainContext.getApplicationContext().sendBroadcast(i);
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
return null;
}
};
if (Build.VERSION.SDK_INT >= 11) async.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else async.execute();
}
public void stop_UDP_Server()
{
Server_aktiv = false;
}
}
我将接收到的数据发送到一个 BroadcastReceiver,你可以在那里对数据做任何你想做的事情.
I send the received data to an BroadcastReceiver and there you can do what ever you want to with the data.
现在我的客户发送数据.在这段代码中我发送了一个广播,但我认为更改发送到直接IP或其他东西的代码是没有问题的.
And now my client to send the data. In this code I send a broadcast, but I think it will be no problem to change the code for sending to a direct IP or something.
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.os.Build;
public class UDP_Client
{
private AsyncTask<Void, Void, Void> async_cient;
public String Message;
@SuppressLint("NewApi")
public void NachrichtSenden()
{
async_cient = new AsyncTask<Void, Void, Void>()
{
@Override
protected Void doInBackground(Void... params)
{
DatagramSocket ds = null;
try
{
ds = new DatagramSocket();
DatagramPacket dp;
dp = new DatagramPacket(Message.getBytes(), Message.length(), Main.BroadcastAddress, Main.SERVER_PORT);
ds.setBroadcast(true);
ds.send(dp);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (ds != null)
{
ds.close();
}
}
return null;
}
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
}
};
if (Build.VERSION.SDK_INT >= 11) async_cient.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else async_cient.execute();
}
这是从主类实例化类的方法.
And here is how you instantiate the classes from your main class.
//start UDP server
Server = new UDP_Server();
Server.runUdpServer();
//UDP Client erstellen
Client = new UDP_Client();
以及如何与客户端发送消息.
And here how to send a message with the client.
//Set message
Client.Message = "Your message";
//Send message
Client.NachrichtSenden();
要停止 UDP_Server,只需将 Server.Server_aktiv 设置为 false.
To stop the UDP_Server, just set Server.Server_aktiv to false.
要设置上面的消息,你也可以写一个setMessage(String message)"方法或类似的东西.
To set the message above u can also write a "setMessage(String message)" methode or something like that.
相关文章