Android UDP socket sends data only once? - android

I'm pretty new to writing Android apps, and I wanted to write a piece of code that broadcasts the sensor data at a regular interval, say 1 second. Searching open-source codes I managed to write a sender class as below:
public class Sender extends Thread {
private static final String TAG = "Sending";
private static final int PORT = 12346;
private static final int TIMEOUT_MS = 500;
private static final int BUF_SIZE = 1024;
private WifiManager mWifi;
Sender(WifiManager wifi) {
mWifi = wifi;
}
public void run() {
try {
DatagramSocket socket = new DatagramSocket(PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendData(socket);
socket.close();
Thread.sleep(1000);
}
catch (IOException ioe) {
Log.e(TAG, "Couldn't send data", ioe);
}
catch (InterruptedException ie) {
Log.e(TAG, "Can't sleep", ie);
}
}
private void sendData(DatagramSocket socket) throws IOException {
byte[] buf = new byte[BUF_SIZE];
buf = object.toString().getBytes();
InetAddress addr = InetAddress.getByName("192.168.0.255"); // TO FIX
DatagramPacket packet = new DatagramPacket(buf, buf.length, addr, PORT);
socket.send(packet);
}
public void main(String[] args) {
new Sender(null).start();
while (true) {
}
}
}
And here's how I start it from within the onCreate method:
public void onCreate(Bundle savedInstanceState) {
...
new Sender((WifiManager) getSystemService(Context.WIFI_SERVICE)).start();
...
}
Now, if I open Wireshark on my laptop, I only see one packet sent at the time the app is started instead of every one second.
Could someone please point out where I did wrong? Honestly I'm not that familiar with threads and stuff, so I may just be missing something obvious here...
EDIT
OK, so the run method must be looped. See corrected code in the answer below.

Here's the corrected run method code:
public void run() {
while (true) {
try {
DatagramSocket socket = new DatagramSocket(PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendData(socket);
socket.close();
Thread.sleep(1000);
}
catch (IOException ioe) {
Log.e(TAG, "Couldn't send data", ioe);
}
catch (InterruptedException ie) {
Log.e(TAG, "Can't sleep", ie);
}
}
}

Related

How to solve delay in Inputstream.read() in android?

I am working on a Bluetooth multiplayer game project.I followed the android Bluetooth overview https://developer.android.com/guide/topics/connectivity/bluetooth strictly.I used the following code to read and write data:-
public class MyBluetoothService {
private static final String TAG = "MY_APP_DEBUG_TAG";
private Handler handler; // handler that gets info from Bluetooth service
// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
public static final int MESSAGE_READ = 0;
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_TOAST = 2;
// ... (Add other message types here as needed.)
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private byte[] mmBuffer; // mmBuffer store for the stream
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams; using temp objects because
// member streams are final.
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating input stream", e);
}
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Error occurred when creating output stream", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
mmBuffer = new byte[1024];
int numBytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs.
while (true) {
try {
// Read from the InputStream.
numBytes = mmInStream.read(mmBuffer);
// Send the obtained bytes to the UI activity.
Message readMsg = handler.obtainMessage(
MessageConstants.MESSAGE_READ, numBytes, -1,
mmBuffer);
readMsg.sendToTarget();
} catch (IOException e) {
Log.d(TAG, "Input stream was disconnected", e);
break;
}
}
}
// Call this from the main activity to send data to the remote device.
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
// Share the sent message with the UI activity.
Message writtenMsg = handler.obtainMessage(
MessageConstants.MESSAGE_WRITE, -1, -1, mmBuffer);
writtenMsg.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Error occurred when sending data", e);
// Send a failure message back to the activity.
Message writeErrorMsg =
handler.obtainMessage(MessageConstants.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString("toast",
"Couldn't send data to the other device");
writeErrorMsg.setData(bundle);
handler.sendMessage(writeErrorMsg);
}
}
// Call this method from the main activity to shut down the connection.
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close the connect socket", e);
}
}
}
}
For writing data I am using the following code:-
String[] myString={"HI!","How Are YOU"};
mConnected.write(Arrays.toString(myString).getBytes());
But I see that inputstream.read() is receiving data quite late after another device is sending the data.I found some questions regarding this,but none of them seem to provide a satisfactory answer.Any suggestion will be highly helpful.
After
mmOutStream.write(bytes);
try to call:
mmOutStream.flush();
this will cause the bytes to be sent immediately.
https://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html#flush()

Android WiFi Direct client socket timeout

I'm new to Android, somewhat new to socket programming. I have two devices, running Android 5.1, connected with WiFi direct (not sure if that's relevant). I have a service where the server listens for a request on a socket, then returns a reply back to the client.
Likewise the client code sends a request and listens for the reply from the server. The server is sending the response, but the client never gets the message and the socket times out.
Server test code:
while (true) {
try {
Log.i(TAG, "test waiting for a request");
mServer = new ServerSocket(PORT);
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
String msg = "This is my reply.";
OutputStream outputStream = socket.getOutputStream();
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(msg);
out.flush();
out.close();
} catch (SocketException e) {
Log.e(TAG, "Socket Accept Interrupted", e);
} catch (IOException e) {
Log.e(TAG, "Socket Failure", e);
} finally {
if (mServer != null && mServer.isBound()) {
try {
mServer.close();
} catch (IOException ioException) {
Log.e(TAG, "Failed to close socket trying to recover from SocketException", ioException);
}
}
}
}
Client test code:
Socket socket = null;
SocketAddress addr = new InetSocketAddress(host, PORT);
int socketTOms = 5000;
try {
socket = new Socket(host, PORT);
socket.setKeepAlive(false);
String syncReq = "Request to server.";
//Send Request//
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
socket.setSoTimeout(socketTOms);
//Rcv reply//
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
} catch (SocketTimeoutException e) {
Log.e(TAG, "Timeout while reading from socket: timeout=" + socketTOms);
} catch (Exception e) {
Log.e(TAG, "Exception", e);
} finally {
if (socket != null && socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Exception while closing socket", e);
}
}
}
I'm running the server and client on two different devices through Android Studio and can see in the logs that the server receives the request and sends the reply, but the client always throws SocketTimeoutException. I saw else where that socket.setKeepAlive(false) would fix the problem, but it doesn't seem to have any effect.
Seems simple enough, but I can't see what I'm missing here.
May be try this line of code before infinite loop mServer = new ServerSocket(PORT);
Did you try to create thread in sever side app. This makes the process to run in parallel so that while server is waiting for request the application does not gets hang. First of all try this code for localhost . To find Inetaddress just use InetAddress.getLocalHost(). Then run this. For communication with different devices there is service provided that is called (NSD) (Network Service Discovary).
But if you want to run this way I have written a code for you.
Server side code
TextView textView;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
button.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
connect();
}
}
);
}
public void connect()
{
MyServer myServer= new MyServer();
myServer.setEventListener(this);
myServer.startListening();
}
#Override
public void Display(String message) {
textView.setText("Client - "+ message);
}
}
Client side code
TextView textView;
Button button;
Thread mThread;
Socket clientSocket;
Button sendBtn;
public String userText1;
ObjectOutputStream output;
EditText editText;
Object userText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=(TextView)findViewById(R.id.textView);
button=(Button)findViewById(R.id.button);
sendBtn=(Button)findViewById(R.id.sendBtn);
editText=(EditText)findViewById(R.id.editText);
sendBtn.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
userText=editText.getText().toString();
start();
}
}
);
public void start()
{
mThread= new Thread(new Runnable() {
#Override
public void run() {
try {
clientSocket = new Socket("127.0.0.1", 2001);
Log.v("binaya", "client socket created");
output = new ObjectOutputStream(clientSocket.getOutputStream());
output.writeObject(userText);
Message serverObj = Message.obtain();
ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());
String strMsg = input.readObject().toString();
serverObj.obj = strMsg;
mHandler.sendMessage(serverObj);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
});
mThread.start();
}
Handler mHandler= new Handler()
{
#Override
public void handleMessage(Message msg) {
msgDisplay(msg.obj.toString());
}
};
private void msgDisplay(String msg) {
textView.setText("Server - " + msg);
}
We have used handler because we cannot touch user interface from inside runnable in this case.
Thanks
Figured this out ....
On the client side I was using outputStream.write(...) to send the request to the server as in:
String syncReq = "Request to server.";
OutputStream outputStream = socket.getOutputStream();
outputStream.write(syncReq.getBytes());
But reading it on the server with BufferedReader.readLine():
Socket socket = mServer.accept(); //Block to receive message //
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Log.i(TAG, "Message received! " + in.readLine());
My problem was that outputStream.write(...) does not append a '\n' at the end of the String, but in.readLine() on the server expects it. Therefore the server was blocking while waiting for '\n'; which in turn caused the client socket to timeout.

How to listen for incoming messages from sockets of threads to update a Listview in android?

I am developing an android application in which I have to create a multiple clients connection with one server. At the server side I am creating a new thread for every client and it is working fine, but in the new created thread where I am listening for a messages from socket and updating a list view created in a fragment, it is not getting updated. Please help me to solve this issue.
public class ClientSocketHandler extends Thread {
private static final String TAG = "ClientSocketHandler";
//private Handler handler;
// private ChatManager chat;
private InetAddress mAddress;
InputStream dataInputStream=null;
OutputStream dataOutputStream=null;
static String msgToSend="";
int i;
char c;
String newMsg="";
Boolean flag=true;
WiFiChatFragment frg;
Handler handler;
public ClientSocketHandler(InetAddress groupOwnerAddress) {
this.mAddress = groupOwnerAddress;
//this.handler=handl;
}
#Override
public void run() {
Socket socket = new Socket();
try {
socket.bind(null);
socket.connect(new InetSocketAddress(mAddress.getHostAddress(),
WiFiServiceDiscoveryActivity.SERVER_PORT), 5000);
Log.d(TAG, "Launching the I/O handler");
dataInputStream = socket.getInputStream();
dataOutputStream = socket.getOutputStream();
while (true) {
while(flag){
if((i=dataInputStream.read())!=1){
frg.pushMessage(newMsg);
newMsg="";
flag=false;
}
else{
c=(char)i;
newMsg+=c;}
}
if(!msgToSend.equals("")){
dataOutputStream.write(msgToSend.getBytes());
dataOutputStream.flush();
msgToSend = "";
}
}
} catch (IOException e) {
e.printStackTrace();
try {
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return;
}
}
public static void sendMsg(String msg){
msgToSend = msg;
}
}
I think this can happen of any of the following this is not handled.
1. Set the list adapted
2. Check that data is received on client and added to the data source.
3. Call the notifyDataSetChanged() after adding the data to data source for ListView.

ServerSocket Android

Hey community I have the following ServerSocket which should listen to port 53000 and log any received data. However, I cannot seem to get past the server.accept() blocking call.
public void run() {
SocketServer server = new ServerSocket(53000);
//---buffer store for the stream---
byte[] buffer = new byte[1024];
//---bytes returned from read()---
int bytes;
//---keep listening to the InputStream until an
// exception occurs---
while (true) {
try {
socket = server.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e){
server.close();
Log.e(TAG, e.getMessage());
}
}
}
I have also given the application the INTERNET permission in the Manifest file.
()
To add to the mystery, I have also verified client responses get sent to that port.
Is there something in particular I need to do to make this work?
Thanks.
Your code is very messy and won't even compile. I made some adjustments so that i could test your code, and it's working fine. Here is the test application I used:
package com.test.stackoverflow
import java.io.BufferedReader;
public class ServerSocketTestActivity extends Activity {
/** Called when the activity is first created. */
private static String TAG = "ServerSocketTest";
private ServerSocket server;
Runnable conn = new Runnable() {
public void run() {
try {
server = new ServerSocket(53000);
while (true) {
Socket socket = server.accept();
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String str = in.readLine();
Log.i("received response from server", str);
in.close();
socket.close();
}
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(conn).start();
}
#Override
protected void onPause() {
super.onPause();
if (server != null) {
try {
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Using this code and netcat running via adb shell I was able to connect and communicate with the application.
When working with The Client Declare these methods
To access Streams
// gets the input stream // ObjectInputStream input;
// gets the output stream // ObjectOutputStream output;
// ServerSocket server;
// Socket connection;
maybe you have a another class to access the socket;
server = new ServerSocket(5001, 100);
// step 1 create socket connection
server = new ServerSocket(5001, 100);
while(the condition is true)
// step 2 wait for connection
// step 3 get streams
// step 4 : process the connection
// step 5 : close connection

How to receive data using UDP in Android?

I use the following code to receive the data from a particular port. It's not working in Android. But sending data to particular port is working fine.
public class UDPDemo extends Activity {
private TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.recv_message);
try {
DatagramSocket clientsocket=new DatagramSocket(9876);
byte[] receivedata = new byte[1024];
while(true)
{
DatagramPacket recv_packet = new DatagramPacket(receivedata, receivedata.length);
Log.d("UDP", "S: Receiving...");
clientsocket.receive(recv_packet);
String rec_str = new String(recv_packet.getData());
tv.setText(rec_str);
Log.d(" Received String ",rec_str);
InetAddress ipaddress = recv_packet.getAddress();
int port = recv_packet.getPort();
Log.d("IPAddress : ",ipaddress.toString());
Log.d(" Port : ",Integer.toString(port));
}
} catch (Exception e) {
Log.e("UDP", "S: Error", e);
}
}
}
If you are using the emulator you may need setup redirects, remember the emulator is behind a virtual router.
In other words, type these commands in;
telnet localhost 5554
redir add udp:9876:9876
and try again.
Used Port numbers
Create Datagram packet
try {
mDataGramSocket = new DatagramSocket(Config.PORT_NUMBER);
mDataGramSocket.setReuseAddress(true);
mDataGramSocket.setSoTimeout(1000);
} catch (SocketException e) {
e.printStackTrace();
}
Call below function through AsyncTask
Create Function to receive infinitely
public void receive() {
String text;
byte[] message = new byte[1500];
DatagramPacket p = new DatagramPacket(message, message.length);
try {
while (true) { // && counter < 100 TODO
// send to server omitted
try {
mDataGramSocket.receive(p);
text = new String(message, 0, p.getLength());
// If you're not using an infinite loop:
//mDataGramSocket.close();
} catch (SocketTimeoutException | NullPointerException e) {
// no response received after 1 second. continue sending
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
// return "error:" + e.getMessage();
mReceiveTask.publish("error:" + e.getMessage());
}
// return "out";
}

Categories

Resources