This is my first post at the stackoverflow...
I am dealing with android app few weeks ago so my Knoledge is limited.
I want to send and receive UDP pakets enery 5 secs.I found example code BUT it use a button for that.
That is the code:
class Client implements Runnable
{
public Client()
{
}
#Override
public void run() {
try
{
String outMessage = txtOutMessage.getText().toString();
String outIp = txtOutIp.getText().toString();
int outPort = Integer.parseInt(txtOutPort.getText().toString());
InetAddress serverAddr = InetAddress.getByName(outIp);
DatagramSocket socket = new DatagramSocket();
byte[] buf = outMessage.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, outPort);
socket.send(packet);
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(receivePacket);
final String recvMsg = new String(receivePacket.getData()).trim();
runOnUiThread(new Runnable()
{
#Override
public void run() {
txtInMessage.setText(recvMsg);
}
});
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
}
Please advice
Thanks in advanced
Nikos
Why not try using a thread? Something like this would work:
//create a thread
Thread t = new Thread()
{
#Override
public void run()
{
while (true)
{
try
{
//do your stuff
Thread.sleep(5000);
//thread to sleep for 5 seconds (5000 milliseconds)
} catch (InterruptedException ie)
{
ie.printStackTrace(); //catch the exception for thread.sleep
}
}
}
};
t.start(); //start the thread
I have something very similar but mine checks for incoming data ever 100 milliseconds and checks for outgoing data every 250 milliseconds, I have one thread for each of those, I then have a separate thread which runs every 20 seconds to check the socket to make sure its alive and to do some socket validation, and to create a new socket if its failed.
Related
I am trying to pass keyboard values to an android client to push it to a server.
I am using threads, but don't want to run a new thread or call socketconnect each time. Instead, I want to run a single thread, open socket connection and then use the same thread and already opened socket to push some values to server from keyboard.
A runnable example with handler will work in my case but I don't know how to code it. ASYNCTASKS wont help as it would open connection again and again.
My Connection class is
class conThread implements Runnable {
public Handler dataHandler = new Handler() ;
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);//}
} catch (IOException e) {
e.printStackTrace();
}
}
}
**and my button has got the below code to send values to the thread for passing on to the server **
public void dataSend(View view) {
conThread con = new conThread();
new Thread(con).start();
con.dataHandler.post(new Runnable() {
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream());
Log.d("Client", "S: data");
out.print("3333");
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
I get connected to the server but get a crash after that.
I attempting to build a remote controller for my laptop using my phone.
I written a server application that running on my laptop, the remote app used as a client to the server application.
I want to implement a mouse pad, the problem is when I am moving my finger over the "touch pad" too fast, I am receiving read time out on server side after few iterations.
Server code
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(20);
Runnable serverTask = new Runnable()
{
#Override
public void run()
{
ServerSocket serverSocket = null;
try
{
serverSocket = new ServerSocket(DEFAULT_PORT);
serverSocket.setReuseAddress(true);
_working = true;
while (_working)
{
Socket clientSocket = serverSocket.accept();
clientSocket.setSoTimeout(10000);
clientProcessingPool.submit(new ClientTask(clientSocket));
}
}
catch (IOException e)
{
System.err.println("Unable to process client request");
e.printStackTrace();
}
finally
{
try
{
if (serverSocket != null)
{
serverSocket.close();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
private class ClientTask implements Runnable
{
private final Socket clientSocket;
private ClientTask(Socket clientSocket)
{
this.clientSocket = clientSocket;
}
#Override
public void run()
{
System.out.println("Got a client !");
try
{
System.out.println("Connected!");
DataOutputStream dOut = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream dIn = new DataInputStream(clientSocket.getInputStream());
String request = dIn.readUTF();
parseRequest(request);
System.out.println("request=" + request);
dOut.writeUTF("Got the command");
dOut.flush(); // Send off the data
dIn.close();
dOut.close();
clientSocket.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I thought maybe I will send the requests only if the distance from the starting position to end position is bigger than STEPS(a constant) and only then send the request. But I think the mouse won`t move fluidly.
Thanks.
RXAndroid and RXJava are perfect for asynchronously handling these request and will allow you to add a debounce to the frequent requests. Check out Reactive.io
I have android service that creates new Thread.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
t = new ConnectionThread();
t.start();
return Service.START_NOT_STICKY;
}
On that Thread I'm opening socket connection and keeping it alive. It looks like this
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
}
On this Thread I also have method that can send JSON message to the server. I call it from the service and service command is called from the fragment (on buttonclick) and it works fine.
public String sendJSON() {
JSONObject messageJson = new JSONObject();
JSONObject mJson = new JSONObject();
try {
mJson.put("Type", "ReadyToBind");
messageJson.put("DeviceID", "myDeviceID");
messageJson.put("AllowFastBind", true);
mJson.put("Message", messageJson);
} catch (JSONException e) {
e.printStackTrace();
}
PrintWriter out = null;
try {
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
out.println(mJson);
} catch (IOException e) {
e.printStackTrace();
}
return message2;
}
But main problem is that server giving response in 3 seconds. This means it can give response instantly or it could wait 0-3 seconds and give different response.
How should I Implement listener to the server? It should listen to the commands recieved from server and react with the application (change current fragment UI).
I tried to create second thread on sendJson() method
mThread = new ConnectionThread2ndLevel(socket);
mThread.start();
long start = System.currentTimeMillis();
long end = start + 3 * 1000; // 3 seconds * 1000 ms/sec
while (System.currentTimeMillis() < end){
message2 = mThread.getMessage();
}
And on that Thread run() method i just read and on getMessage() I just return recieved message.
scanner = new Scanner(socket.getInputStream());
message2Thread = scanner.nextLine();
But this freezes application and user nothing can do during that time. Also not always I've got response from the server (maybe I got response and on while loop read blank line and then return it back.
So please, can you give me an advice or example how to do it in right way? It would be great that server listener could recieve message and instantly initiate changes on fragment (UI).
I'm trying to make a simple chatting app, using socket communication.
My goal is to send and receive text and images(from smartphone gallery) successfully.
Text part successful, but I'm having trouble with images.
I wrote a code using dataInput/OutputStream, and below is the code, which is establishing socket connection for image transfer, using bytearray(The app use different port for text and image).
class image_connection_thread extends Thread{
public boolean flag=true;
public void run(){
try{
socket2 = new Socket(Ip,port_img);
//Imgage Streams
img_output= new DataOutputStream(socket2.getOutputStream());
img_input= new DataInputStream(socket2.getInputStream());
while(flag)
{
///////////////////
img_input.readFully(byte_input);
**////// This line makes problem(App dies). But no exception message occurs. ////**
if(byte_input==null)
break;
image_received=BitmapFactory.decodeByteArray(byte_input, 0, byte_input.length);
Message Msg = new Message();
Msg.obj=image_received;
handler_img.sendMessage(Msg);
}
socket2.close();
}catch(Exception e)
{
tv_Text.append(e.getMessage()+"connection failed3\n");
}
}
}
While loop is to wait for input bytearray from server. Handler displays decoded bytearray on display.
--> img_input.readFully(byte_input); I think this line makes problem. I checked that handler works well, and with empty while block, App didn't die.
What would be the problem?
Server side code is shown below.(message threads are omitted)
public class server
{
public static void main(String[] args) {
Thread thread1=new port1_thread();
Thread thread2=new port2_thread();
thread1.start();
thread2.start();
}
}
class port2_thread extends Thread
{
ServerSocket serversocket = null;
public void run()
{
try
{
serversocket = new ServerSocket(9003);
while(true)
{
Socket socket = serversocket.accept();
Thread thread= new image_thread(socket);
thread.start();
}
}catch(Exception e){System.out.println("1-2"+e.getMessage());}
}
}
class image_thread extends Thread
{
static ArrayList<DataOutputStream> list2 = new ArrayList<DataOutputStream>();
Socket socket;
DataOutputStream output2 = null;
image_thread(Socket socket)//constructor
{
this.socket=socket;
try //data output stream
{
output2 = new DataOutputStream(socket.getOutputStream());
list2.add(output2);
}
catch (Exception e)
{
System.out.println("22"+e.getMessage());
}
}
public void run()
{
try
{
//output2= new DataOutputStream(socket.getOutputStream());
DataInputStream input2=new DataInputStream(socket.getInputStream());
while(true)
{
for (DataOutputStream output2 : list2)
{
byte[] b = new byte[1024];
input2.readFully(b);
output2.write(b);
output2.flush();
}
}
}catch(Exception e){System.out.println("33"+e.getMessage());}
finally
{
list2.remove(output2);
try
{
socket.close();
}catch(Exception ignored){}
}
}
}
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);
}
}
}