我正在创建用于与TCP套接字服务器通信的Android应用。 TCP服务器是ESP8266 WiFi模块。应用程序和服务器每隔1秒钟就有一次通信,但我发现2个问题。
TCP任务代码
public class SingleControlWiFiModule extends AsyncTask<String[], Task, Task>{
private static final int CONNECT_TIMEOUT = 5000;
private static final int RESPONSE_TIMEOUT = 5000;
private int connectionTimeout, responseTimeout;
private String[] request;
//TCP
private Network network;
//Interface
private OnSingleResult result;
//Other
private static final String ERR_CON = "Connection Timeout!";
private static final String ERR_RES = "Response Timeout!";
public static final String ERR_OTHER = "System Error";
private static final String TAG = "SingleControl";
public SingleControlWiFiModule(Network network, OnSingleResult result){
this.network = network;
this.result = result;
this.connectionTimeout = CONNECT_TIMEOUT;
this.responseTimeout = RESPONSE_TIMEOUT;
}
public void startTask(String ip, String[] request){
if (ip==null | request==null){ return; }
//Must create New SingleControlWiFiModule object before Call This function
this.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, new String[]{ip}, request);
}
private String[] getResponse(Socket socket, String[] request){
try {
// Create PrintWriter object for sending messages to server.
PrintWriter outWrite = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
//Send message
for (String c : request){
outWrite.print(c+",");
}
outWrite.flush();
Log.w(TAG, "Send request success :: "+ Arrays.toString(request));
//Create object for receiving message response from server.
InputStreamReader inputStream = new InputStreamReader(socket.getInputStream());
long start = System.currentTimeMillis(); boolean timeout = false;
//Waiting
while (!inputStream.ready()){
timeout = (System.currentTimeMillis() - start)>responseTimeout;
if (timeout){
return new String[]{ERR_RES};
}
}
//Reset start time
start = System.currentTimeMillis();
//Read response message
StringBuilder s = new StringBuilder("");
int i = 0; String []buffer = new String[Constant.BUFF_MAX];
while (inputStream.ready()){
//Int value
int a = inputStream.read();
//Convert int to char
char data = (char)a;
//Check value
if (a>255){ data = '\0'; } //Empty
//Check syntax ',' mean ending each word. So Server must send Ex: Hello,You,
if (data==','){
buffer[i] = s.toString(); ///Add message to String array
s = new StringBuilder(""); ///Clear string
i++;
}else {
s.append(data); //Create word string
}
//Check Timeout
timeout = (System.currentTimeMillis() - start)>responseTimeout;
if (timeout && !inputStream.ready()){ return new String[]{ERR_RES}; }
}
buffer = i > 0 ? Arrays.copyOf(buffer, i) : new String[]{s.toString()}; //Re-size buffer
Log.w(TAG, "Server response :: " + Arrays.toString(buffer));
return buffer;
} catch (SocketTimeoutException e){
e.printStackTrace();
return new String[]{ERR_CON};
} catch (IOException e) {
e.printStackTrace();
return new String[]{ERR_OTHER};
}
}
@Override
protected Task doInBackground(String[]... strings) {
request = strings[1];
final String host = strings[0][0];
Log.w(TAG, "Try connect: "+host+" By timeout connection: "+connectionTimeout+" response: "+responseTimeout);
final Socket socket = new Socket();
try {
network.bindSocket(socket);
socket.setKeepAlive(false);
socket.setTcpNoDelay(true);
socket.connect(new InetSocketAddress(host, Constant.PORT), connectionTimeout);
//Get response
Task task = new Task(host, Constant.PORT, request, getResponse(socket, request));
//Disconnect server
socket.close();
//Return result
return task;
} catch (SocketTimeoutException e){
e.printStackTrace();
return new Task(host, Constant.PORT, request, new String[]{ERR_CON});
} catch (IOException e) {
e.printStackTrace();
return new Task(host, Constant.PORT, request, new String[]{ERR_OTHER});
}
}
@Override
protected void onPostExecute(Task task) {
super.onPostExecute(task);
if (task!=null){
Log.w(TAG, "Finish :: request: "+Arrays.toString(task.request)+" response: "+Arrays.toString(task.response));
if (result!=null){
result.onFinish(task);
}
}
}
interface OnSingleResult{
void onFinish(Task task);
}
}
MainAcivity
@Override
protected void onStart() {
super.onStart();
conManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder wifiBuilder = new NetworkRequest.Builder();
wifiBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
if (conManager!=null && Function.isConnectWifi(this)){
conManager.requestNetwork(wifiBuilder.build(), networkCallback);
}else {
statusText.setText(R.string.no_network);
statusText.setVisibility(View.VISIBLE);
}
}
@Override
protected void onStop() {
super.onStop();
//Stop loop reading
stopLoopHandle();
conManager.unregisterNetworkCallback(networkCallback);
}
private void readAdvanceParameter(){
singleModule = new SingleControlWiFiModule(wifiNetwork, singleResult);
singleModule.startTask(ipConnect, new String[]{Constant.ADVANCE_DATA});
}
private ConnectivityManager.NetworkCallback networkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
Log.w(TAG, "Network available: "+network);
//Set Network
wifiNetwork = network;
//Create Handler for loop reading
handler = new Handler();
//Start reading
readAdvanceParameter();
}
[@Override
public void onLost(Network network)][1] {
super.onLost(network);
Log.w(TAG, "Network loss: "+network);
statusText.setText(R.string.no_network);
statusText.setVisibility(View.VISIBLE);
//Stop loop
stopLoopHandle();
}
};
private SingleControlWiFiModule.OnSingleResult singleResult = new SingleControlWiFiModule.OnSingleResult() {
@Override
public void onFinish(Task task) {
Log.w(TAG, "Read parameter finish :: Value: "+ Arrays.toString(task.response));
//Check result
if (task.response.length>=UNIT_2016_2034.length){
//Close Status
statusText.setVisibility(View.INVISIBLE);
//Set item
items.clear(); String d, t, f; int offset = 2016;
for (int i=0; i<UNIT_2016_2034.length; i++){
f = desFunction[i];
d = task.response[i];
if (i>0 && i<5){
d = String.valueOf(ControlActivity.getActualIndoorTemp(getIntegerOf(d)));
}else if (i==11 | (i>12 && i<15)){
d = onePoint.format(getIntegerOf(d)/10);
}else if (i==12){
d = twoPoint.format(getIntegerOf(d)/100);
}else if (i==10){
t = Integer.toHexString(getIntegerOf(d));
Log.w(TAG, "In: "+d+" Hex: "+t);
d = getErrorDetail(t);
f = f + " ["+t+"]";
}
Parameter p = new Parameter(offset+i, f, d, UNIT_2016_2034[i]);
items.add(p);
}
//Update adapter
adapter.notifyDataSetChanged();
//Visible item
if (itemView.getVisibility()==View.INVISIBLE){
itemView.setVisibility(View.VISIBLE);
loadProgress.setVisibility(View.INVISIBLE);
}
}else {
//Failed reading
Log.e(TAG, "Read parameter Failed: "+task.response[0]);
statusText.setText(task.response[0]);
statusText.setVisibility(View.VISIBLE);
//Stop loop
if (task.response[0].equals(SingleControlWiFiModule.ERR_OTHER)){
singleModule.cancel(true);
stopLoopHandle();
}
}
//Call loop reading handle
if (handler!=null){
handler.removeCallbacks(loopRun);
handler.postDelayed(loopRun, INTERVAL);
}
}
};
在测试中,我将服务器设置为响应客户端发送的相同消息。
02-24 15:54:26.478 23501-23596/com.apyeng.tasakicentral W/SingleControl:
Send request success :: [12]
02-24 15:54:27.275 23501-23581/com.apyeng.tasakicentral W/Advance: Network loss: 197
02-24 15:54:27.375 23501-23581/? I/Process: Sending signal. PID: 23501 SIG: 9
如何解决这个问题?