I have a slight problem, I have a TCP class which connects to a server, transfers data then closes, this all works well except for if I connect, then stop it, it works, if I keep on doing this, it works, but on the fifth time the connection hangs without any error and doesn't transfer any data.. I've got no idea how to fix this... This is my TCP class code:
package com.millennium.isynccrm.Classes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.util.Log;
public class TcpClient {
public static boolean connected = false;
private static Socket socket;
private static boolean pause = false;
private static SyncClient syncClient = new SyncClient();
public static int sendCount = 0;
public static int receiveCount = 0;
private static AsyncTask<?, ?, ?> sendAsyncTask;
private static AsyncTask<?, ?, ?> receiveAsyncTask;
public TcpClient() { }
public void send (String line) {
if (!connected) connect();
while (!connected) { }
sendAsyncTask = new SenderThread().execute(line);
}
public void disconnect() {
try {
if(connected == true) {
socket.close();
connected = false;
sendCount = 0;
receiveCount = 0;
if (receiveAsyncTask.getStatus().name().equals("RUNNING")) {
receiveAsyncTask.cancel(true);
}
if (sendAsyncTask.getStatus().name().equals("RUNNING")) {
sendAsyncTask.cancel(true);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void pauseReceivingForTimeInterval(int milliseconds) {
pause = true;
new CountDownTimer(milliseconds, 0) {
public void onT开发者_C百科ick(long millisUntilFinished) { }
public void onFinish() {
pause = false;
}
}.start();
}
private void connect() {
new Thread(new Runnable() {
public void run() {
try {
if (connected == false) {
socket = new Socket("192.168.1.1", 80);
connected = true;
sendCount = 0;
receiveCount = 0;
try {
if (receiveAsyncTask.getStatus().name().equals("FINISHED")) {
receiveAsyncTask = new RecieverThread().execute("");
} else if (receiveAsyncTask.getStatus().name().equals("RUNNING")) {
receiveAsyncTask.cancel(true);
receiveAsyncTask = new RecieverThread().execute("");
}
} catch (Exception e) { receiveAsyncTask = new RecieverThread().execute(""); }
}
} catch (UnknownHostException e) {
connected = false;
e.printStackTrace();
} catch (IOException e) {
connected = false;
e.printStackTrace();
}
}
}).start();
}
private static PrintWriter output;
private static BufferedReader input = null;
private class RecieverThread extends AsyncTask<String, Void, String> {
protected String doInBackground(String... line) {
while (pause) { }
try {
receiveCount++;
if (receiveCount == 1) input = new BufferedReader(new InputStreamReader(socket.getInputStream()), 8 * 1024);
return input.readLine();
} catch (IOException e) {
Log.d("error", "stop");
}
return "stop";
}
protected void onPostExecute(String result) {
if (result == null) return;
else if (!result.equals("") && !result.equals("stop")) syncClient.recieveMessage(result);
else if (!result.equals("stop")) receiveAsyncTask = new RecieverThread().execute("");
}
}
private class SenderThread extends AsyncTask<String, Void, String> {
protected String doInBackground(String... line) {
while (pause) { }
sendCount++;
if (sendCount == 1) {
try {
output = new PrintWriter(socket.getOutputStream(),true);
} catch(Exception e) { e.printStackTrace(); }
}
String msg = line[0] + "\r\n";
output.print(msg);
output.flush();
return "";
}
protected void onPostExecute(String result) {
}
}
}
As you can see another class sends a line to this class to send to the server, then a Async task sends it and another Async task receives it and passes it onto another class which processes it and so on. On the UI I have a start button which when is pressed turns into a stop button and when stop is pressed it calls the 'disconnect' function in here.
I'm not too sure wherever I have done my RecieverThread AsyncTask is correct, it waits for a line from the socket then passes it on and restarts it self to listen for another line, is this a 'good' way of doing this? Or is it a terrible way (which I imagine it is). To be honest I think this class is very 'messy' and I will more than likely be redoing it.
Any suggestion why I can never send data on the fifth time I connect to the server? (One last note, the server is not to blame here, as we have a iPhone app which does the same thing) (Extra side note.. I'm pretty new to Tcp connections and that sort of stuff, and new to Threading/Async Tasks.) :)
Any help, assistance would be much appreciated (: Thanks!
while (!connected) {}??? that's no way to do asynchronous anything. You are hogging the CPU waiting for something to happen, and preventing it from happening by hogging the CPU. Use a Selector, or do a blocking-mode connect.
精彩评论