Je peux envoyer correctement mes données via le socket UDP, mais lorsque je reçois des données, il continue d'attendre à la commande de réception, je ne sais pas ce qui cause cela. Veuillez consulter mon code ci-dessous.
Je suis en mesure de recevoir correctement les données côté serveur de l'appareil Android, mais lorsque j'envoie des données côté serveur à Android il ne reçoit pas. Mais lorsque j'envoie des données du serveur à tout autre client, par exemple une application PC, il reçoit et affiche les données correctement.
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)
{
}
}
}
Documentation dans Eclipse:
Reçoit un paquet de cette socket et le stocke dans le pack d'arguments. Tous les champs du pack doivent être définis en fonction des données reçues. Si les données reçues sont plus longues que la taille du tampon de paquets, elles sont tronquées. Cette méthode se bloque jusqu'à ce qu'un paquet soit reçu ou qu'un délai expire.
La commande "s.receive(p);
" bloque le thread jusqu'à ce qu'il reçoive les données ou que le délai défini avec setSoTimeout (délai) soit terminé.
J'ai fait 2 cours pour que ma communication se fasse. Premier serveur UDP:
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;
}
}
J'envoie les données reçues à un BroadcastReceiver et là vous pouvez faire ce que vous voulez avec les données.
Et maintenant mon client envoie les données. Dans ce code, j'envoie une diffusion, mais je pense que ce ne sera pas un problème de changer le code pour envoyer à une adresse IP directe ou quelque chose.
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();
}
Et voici comment vous instanciez les classes de votre classe principale.
//start UDP server
Server = new UDP_Server();
Server.runUdpServer();
//UDP Client erstellen
Client = new UDP_Client();
Et voici comment envoyer un message au client.
//Set message
Client.Message = "Your message";
//Send message
Client.NachrichtSenden();
Pour arrêter UDP_Server, définissez simplement Server.Server_aktiv sur false.
Pour définir le message ci-dessus, vous pouvez également écrire une méthode "setMessage (String message)" ou quelque chose comme ça.
Ici, dans cet article, vous trouverez le code détaillé pour établir la socket entre les appareils ou entre deux applications dans le même mobile.
Vous devez créer deux applications pour tester le code ci-dessous.
Dans les deux applications fichier manifeste, ajoutez l'autorisation ci-dessous
<uses-permission Android:name="Android.permission.INTERNET" />
1er code d'application: UDP Client Socket
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TableRow
Android:id="@+id/tr_send_message"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:gravity="center"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true"
Android:layout_alignParentTop="true"
Android:layout_marginTop="11dp">
<EditText
Android:id="@+id/edt_send_message"
Android:layout_width="0dp"
Android:layout_height="wrap_content"
Android:layout_weight="1"
Android:layout_marginRight="10dp"
Android:layout_marginLeft="10dp"
Android:hint="Enter message"
Android:inputType="text" />
<Button
Android:id="@+id/btn_send"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginRight="10dp"
Android:text="Send" />
</TableRow>
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true"
Android:layout_below="@+id/tr_send_message"
Android:layout_marginTop="25dp"
Android:id="@+id/scrollView2">
<TextView
Android:id="@+id/tv_reply_from_server"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" />
</ScrollView>
</RelativeLayout>
DPClientSocketActivity.Java
import Android.os.Bundle;
import Android.os.Handler;
import Android.support.v7.app.AppCompatActivity;
import Android.view.View;
import Android.widget.Button;
import Android.widget.EditText;
import Android.widget.TextView;
import Java.io.IOException;
import Java.net.DatagramPacket;
import Java.net.DatagramSocket;
import Java.net.InetAddress;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class UDPClientSocketActivity extends AppCompatActivity implements View.OnClickListener {
private TextView mTextViewReplyFromServer;
private EditText mEditTextSendMessage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button buttonSend = (Button) findViewById(R.id.btn_send);
mEditTextSendMessage = (EditText) findViewById(R.id.edt_send_message);
mTextViewReplyFromServer = (TextView) findViewById(R.id.tv_reply_from_server);
buttonSend.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_send:
sendMessage(mEditTextSendMessage.getText().toString());
break;
}
}
private void sendMessage(final String message) {
final Handler handler = new Handler();
Thread thread = new Thread(new Runnable() {
String stringData;
@Override
public void run() {
DatagramSocket ds = null;
try {
ds = new DatagramSocket();
// IP Address below is the IP address of that Device where server socket is opened.
InetAddress serverAddr = InetAddress.getByName("xxx.xxx.xxx.xxx");
DatagramPacket dp;
dp = new DatagramPacket(message.getBytes(), message.length(), serverAddr, 9001);
ds.send(dp);
byte[] lMsg = new byte[1000];
dp = new DatagramPacket(lMsg, lMsg.length);
ds.receive(dp);
stringData = new String(lMsg, 0, dp.getLength());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
handler.post(new Runnable() {
@Override
public void run() {
String s = mTextViewReplyFromServer.getText().toString();
if (stringData.trim().length() != 0)
mTextViewReplyFromServer.setText(s + "\nFrom Server : " + stringData);
}
});
}
});
thread.start();
}
}
2e code d'application - socket du serveur UDP
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Button
Android:id="@+id/btn_stop_receiving"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="STOP Receiving data"
Android:layout_alignParentTop="true"
Android:enabled="false"
Android:layout_centerHorizontal="true"
Android:layout_marginTop="89dp" />
<ScrollView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_below="@+id/btn_stop_receiving"
Android:layout_marginTop="35dp"
Android:layout_alignParentLeft="true"
Android:layout_alignParentStart="true">
<TextView
Android:id="@+id/tv_data_from_client"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:orientation="vertical" />
</ScrollView>
<Button
Android:id="@+id/btn_start_receiving"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="START Receiving data"
Android:layout_alignParentTop="true"
Android:layout_centerHorizontal="true"
Android:layout_marginTop="14dp" />
</RelativeLayout>
DPServerSocketActivity.Java
import Android.os.Bundle;
import Android.os.Handler;
import Android.support.v7.app.AppCompatActivity;
import Android.view.View;
import Android.widget.Button;
import Android.widget.TextView;
import Java.io.IOException;
import Java.net.DatagramPacket;
import Java.net.DatagramSocket;
/**
* Created by Girish Bhalerao on 5/4/2017.
*/
public class UDPServerSocketActivity extends AppCompatActivity implements View.OnClickListener {
final Handler handler = new Handler();
private Button buttonStartReceiving;
private Button buttonStopReceiving;
private TextView textViewDataFromClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStartReceiving = (Button) findViewById(R.id.btn_start_receiving);
buttonStopReceiving = (Button) findViewById(R.id.btn_stop_receiving);
textViewDataFromClient = (TextView) findViewById(R.id.tv_data_from_client);
buttonStartReceiving.setOnClickListener(this);
buttonStopReceiving.setOnClickListener(this);
}
private void startServerSocket() {
Thread thread = new Thread(new Runnable() {
private String stringData = null;
@Override
public void run() {
byte[] msg = new byte[1000];
DatagramPacket dp = new DatagramPacket(msg, msg.length);
DatagramSocket ds = null;
try {
ds = new DatagramSocket(9001);
//ds.setSoTimeout(50000);
ds.receive(dp);
stringData = new String(msg, 0, dp.getLength());
updateUI(stringData);
String msgToSender = "Bye Bye ";
dp = new DatagramPacket(msgToSender.getBytes(), msgToSender.length(), dp.getAddress(), dp.getPort());
ds.send(dp);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
});
thread.start();
}
private void updateUI(final String stringData) {
handler.post(new Runnable() {
@Override
public void run() {
String s = textViewDataFromClient.getText().toString();
if (stringData.trim().length() != 0)
textViewDataFromClient.setText(s + "\n" + "From Client : " + stringData);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start_receiving:
startServerSocket();
buttonStartReceiving.setEnabled(false);
buttonStopReceiving.setEnabled(true);
break;
case R.id.btn_stop_receiving:
//Add logic to stop server socket yourself
buttonStartReceiving.setEnabled(true);
buttonStopReceiving.setEnabled(false);
break;
}
}
}