Android Datagram/UDP Server example

Advertisemen

I posted "Java Datagram/UDP Server and Client, run on raspberry Pi" on my another blogspot. And last post show "Android Datagram/UDP Client example". This post show a Datagram/UDP Server run on Android.


MainActivity.java
package com.blogspot.android_er.androidudpserver;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Date;
import java.util.Enumeration;

public class MainActivity extends AppCompatActivity {

private final static String TAG = MainActivity.class.getSimpleName();

TextView infoIp, infoPort;
TextView textViewState, textViewPrompt;

static final int UdpServerPORT = 4445;
UdpServerThread udpServerThread;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);
textViewState = (TextView)findViewById(R.id.state);
textViewPrompt = (TextView)findViewById(R.id.prompt);

infoIp.setText(getIpAddress());
infoPort.setText(String.valueOf(UdpServerPORT));
}

@Override
protected void onStart() {
udpServerThread = new UdpServerThread(UdpServerPORT);
udpServerThread.start();
super.onStart();
}

@Override
protected void onStop() {
if(udpServerThread != null){
udpServerThread.setRunning(false);
udpServerThread = null;
}

super.onStop();
}

private void updateState(final String state){
runOnUiThread(new Runnable() {
@Override
public void run() {
textViewState.setText(state);
}
});
}

private void updatePrompt(final String prompt){
runOnUiThread(new Runnable() {
@Override
public void run() {
textViewPrompt.append(prompt);
}
});
}

private class UdpServerThread extends Thread{

int serverPort;
DatagramSocket socket;

boolean running;

public UdpServerThread(int serverPort) {
super();
this.serverPort = serverPort;
}

public void setRunning(boolean running){
this.running = running;
}

@Override
public void run() {

running = true;

try {
updateState("Starting UDP Server");
socket = new DatagramSocket(serverPort);

updateState("UDP Server is running");
Log.e(TAG, "UDP Server is running");

while(running){
byte[] buf = new byte[256];

// receive request
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet); //this code block the program flow

// send the response to the client at "address" and "port"
InetAddress address = packet.getAddress();
int port = packet.getPort();

updatePrompt("Request from: " + address + ":" + port + "\n");

String dString = new Date().toString() + "\n"
+ "Your address " + address.toString() + ":" + String.valueOf(port);
buf = dString.getBytes();
packet = new DatagramPacket(buf, buf.length, address, port);
socket.send(packet);

}

Log.e(TAG, "UDP Server ended");

} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(socket != null){
socket.close();
Log.e(TAG, "socket.close()");
}
}
}
}

private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces
.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface
.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();

if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "
+ inetAddress.getHostAddress() + "\n";
}

}

}

} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}

return ip;
}
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="vertical"
tools:context="com.blogspot.android_er.androidudpserver.MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />

<TextView
android:id="@+id/infoip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

<TextView
android:id="@+id/infoport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="italic" />

<TextView
android:id="@+id/state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="un-initiated"
android:textSize="20dp"/>

<TextView
android:id="@+id/prompt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18dp"/>
</LinearLayout>


uses-permission of "android.permission.INTERNET" is needed in AndroidManifest.xml

Remark about life-cycle:
In this example, the DatagramSocket server is run in background thread. I haven't handle the life-cycle very well (Actually I don't think any application will have UI like this example). Consider the cases:

Case One:
- Start the app, the activity display on screen and the DatagramSocket opened in associated thread.
- the code socket.receive(packet) block the program flow, so the thread stay here and waiting data request.
- Exit the app. It will set running to false, to request the thread to stop. But the thread is blocked in socket.receive(packet), so it's still running.
- Restart the app, the new thread cannot open the DatagramSocket, because it's still held by old thread.
- Client send a request, the DatagramSocket server response the request and exit socket.receive(packet), and check running and exit.
- In this case, the current activity and associated thread have no DatagramSocket opened!

Case Two:
- Start the app, the activity display on screen and the DatagramSocket opened in associated thread.
- the code socket.receive(packet) block the program flow, so the thread stay here and waiting data request.
- Exit the app. It will set running to false, to request the thread to stop. But the thread is blocked in socket.receive(packet), so it's still running.
- Client send a request, the DatagramSocket server response the request and exit socket.receive(packet), and check running and exit.
- Restart the app, and open the DatagramSocket.
- In this case, the current activity and associated thread can open DatagramSocket and work as expected.


download filesDownload the files .

Advertisemen

Disclaimer: Gambar, artikel ataupun video yang ada di web ini terkadang berasal dari berbagai sumber media lain. Hak Cipta sepenuhnya dipegang oleh sumber tersebut. Jika ada masalah terkait hal ini, Anda dapat menghubungi kami disini.
Related Posts
Disqus Comments
© Copyright 2017 GENERAL INFO FOR ANDROID DEVELOPMENT - All Rights Reserved - Template Created by goomsite - Proudly powered by Blogger