Send and receive data on UDP Socket java android
Documentation in Eclipse:
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.
The "s.receive(p);
" command blocks the thread until it receices data or the timeout set with setSoTimeout(timeout) is over.
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; }}
I send the received data to an BroadcastReceiver and there you can do what ever you want to with the data.
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();
To stop the UDP_Server, just set Server.Server_aktiv to false.
To set the message above u can also write a "setMessage(String message)" methode or something like that.
Here, in this post you will find the detailed code for establishing socket between devices or between two application in the same mobile.
You have to create two application to test below code.
In both application's manifest file, add below permission
<uses-permission android:name="android.permission.INTERNET" />
1st App code: 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>
UDPClientSocketActivity.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(); }}
2nd App Code - UDP Server 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"> <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>
UDPServerSocketActivity.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; } }}