2016-08-01 11 views
1

Ich bin Begginer mit Java-Socket in Android. Ich habe ein Problem und brauche Hilfe, um sie zu lösen.Android-Socket-Prinzip und Ausnahme

Ich bin Verbindung zum Server Socket mit unteren Code und alles ist in Ordnung. aber wenn Anruf trennen Methode und versuchen, wieder zu verbinden ich konfrontiert mit Problem wie socket is null oder BufferedReader Objekt immer Null nach trennen und wieder verbinden. vielleicht ist mein Trennungsweg falsch. Was ist der beste Weg für die Trennung Socket zu irgendeinem Zeitpunkt wie Internet zu stören und wieder zu verbinden?

Hier ist mein Code zum Verbinden und Trennen der Steckdose.

public class HelperSocket { 

public static Socket socket = null; 
public static DataOutputStream writer = null; 
public static BufferedReader reader = null; 
public static DataInputStream inputStream = null; 
public static final String SOCKET_ADDRESS = "aUrlForSocket"; 
public static final int SOCKET_PORT = 6000; 
public static final int SOCKET_TIMEOUT = 30000; 
public static Thread clientThread; 
public static boolean isConnected = false; 

public static boolean connect() { 
    Utils.Log("StartConnect"); 
    if (!isConnected) { 
     clientThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        InetAddress address = InetAddress.getByName(HelperSocket.SOCKET_ADDRESS); 
        socket = new Socket(address.getHostAddress(), SOCKET_PORT); 

        isConnected = true; 
        socket.setSoTimeout(SOCKET_TIMEOUT); 

        writer = new DataOutputStream(socket.getOutputStream()); 
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
        inputStream = new DataInputStream(socket.getInputStream()); 

        while (HelperSocket.isConnected) { 
         Utils.Log("onWhile" + reader.hashCode()); 
         try { 

          if (reader.readLine() != null) { 
           Utils.Log(reader.readLine() + ""); 
          } else { 
           Utils.Log("getNullFromServer"); 
           //data get null here :) 
           disconnect(); 
          } 
         } catch (IOException e) { 
          Utils.Log("ProblemOnReadData" + e.getMessage()); 
          e.printStackTrace(); 
         } 
        } 
       } catch (IOException e) { 
        Utils.Log("SocketProblemAt connect:" + e.getMessage()); 
        e.printStackTrace(); 
       } 
      } 
     }); 
     clientThread.start(); 
    } 

    return true; 
} 

public static boolean disconnect() { 
    isConnected = false; 
    if (!clientThread.isInterrupted()) 
     clientThread.interrupt(); 
    if (socket != null) { 
     Utils.Log("SocketAndAllObjectCleared"); 
     try { 
      socket.shutdownInput(); 
      socket.shutdownOutput(); 
      socket = null; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     /* stream = null; 
     reader = null;*/ 
    } 
    return false; 
} 


} 

Ich erstelle einen Empfänger in der Netzwerkverbindung ändern und muß Steckdose ziehen, wenn das Gerät nicht mit dem Internet verbindet und wieder verbinden, wenn Internet-Verbindung hergestellt.

Der Empfänger:

public class BroadcastChangeNet extends BroadcastReceiver { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (Utils.isNetworkConnected()) { 
      HelperSocket.connect(); 
      Utils.Log("NetWorkConnect"); 
     } else { 
      HelperSocket.disconnect(); 
      Utils.Log("NetWorkDisConnect"); 
     } 
    } 
} 

prüfen Netzsituation:

public static boolean isNetworkConnected() { 
     ConnectivityManager conMgr = 
       (ConnectivityManager) ApplicationClass.context.getSystemService(Context.CONNECTIVITY_SERVICE); 
     NetworkInfo i = conMgr.getActiveNetworkInfo(); 
     if (i == null) 
      return false; 
     if (!i.isConnected()) 
      return false; 
     if (!i.isAvailable()) 
      return false; 
     return true; 
    } 
+0

Sie müssen die Steckdose schließen, nicht herunterfahren. Du liest eine Zeile und wirfst sie dann weg. Sie müssen sich den Abschnitt Benutzerdefinierte Netzwerke des Java-Lernprogramms ansehen. – EJP

+0

@EJP Wenn ich den Socket schließe, kann ich das wiederverwenden? somwhere lesen, wenn close Socket das wieder öffnen kann. – javaddroid

+0

Sie können es nicht erneut verwenden, wenn Sie es entweder herunterfahren oder schließen. Sie müssen eine neue erstellen. – EJP

Antwort

1

Aus meiner Sicht müssen Sie einfach saprate Jave-Klasse erstellen, unten ist mein Code, die ich erfolgreich getestet,

import android.content.Context; 

import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.UnknownHostException; 

/** 
* Created by Kintan Patel on 01-08-2016. 
*/ 
public class SocketConnection { 
    private Socket socket = null; 
    private OutputStream outputStream; 
    private DataOutputStream dataOutputStream; 
    private SessionHelper helper; 

    public String EstablishConnection(String token) { 
    // token = your message that write on socket server 
     String response; 
     try { 

      //socket = new Socket("192.168.0.24", 2129); // Testing Server 
      socket = new Socket("Your IpAddress", PORT NO); 
      outputStream = socket.getOutputStream(); 
      dataOutputStream = new DataOutputStream(outputStream); 
      dataOutputStream.writeUTF(token); 
      BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      response = br.readLine(); 

     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
      response = "UnknownHostException: " + e.toString(); 
      return null; 

     } catch (SocketException e) { 
      e.printStackTrace(); 
      response = "Sorry Fail to connect"; 
      return null; 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      // e.printStackTrace(); 

      response = "Sorry Fail to connect"; 
      return null; 

     } catch (Exception e) { 
      e.printStackTrace(); 
      response = "Server Break"; 
      return null; 

     } finally { 
      if (socket != null) { 
       try { 
        socket.close(); 
        outputStream.close(); 
        dataOutputStream.close(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } 
     } 
     return response; 
    } 
} 

Jetzt von Ihrer Hauptklasse einfach erstellen Sie das Objekt der SocketConnection-Klasse und verwenden EstablishConnection() -Methode,

eg : 

    SocketConnection connection = new SocketConnection(); 
     String token = "message that you want to write on server"; 
     String response = connecation.EstablishConnection(token); 

wenn Sie AsynkTask verwenden möchten als unten ist AsynkTask Code:

private class ActivationTask extends AsyncTask<String, String, String> { 

     @Override 
     protected String doInBackground(String... params) { 
      SocketConnection connection = new SocketConnection(); 
      String token = "getActivation|" + params[0] + "|"; 
      return connection.EstablishConnection(token); 
     } 


     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      progressDialog.show(); 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      progressDialog.dismiss(); 
      if (s != null) { 
       Log.e("RESULT" , s); 



      } 
     } 
    } 
+0

danke @kintanpatel. nur eine kleine frage: wenn ich den sockel schließe, kann ich ihn wieder öffnen und wieder benutzen? – javaddroid

+1

Ja, Sie können es erneut öffnen. – Kintanpatel