2014-10-18 69 views
0

已解決:首次連接後,我沒有重新啓動服務器。現在它工作得很好;)無法通過編程方式接收來自套接字的數據

我在Android設備和PC之間的TCP連接時遇到了麻煩。在PC上,我有tcp服務器與ServerSocket等待接受,並嘗試連接到本地網絡的Android設備。當我將靜態IP地址添加到代碼中時,一切正常,但是當我通過編程(在硬編碼端口上從0到255搜索192.168.1.x)時,它接受連接,但是我無法從ServerSocket接收數據,也無法接收數據來自Android套接字。

在Android上我有3個按鈕的Widget,所有的通信都由AsyncTasks處理。這裏是TCP服務器:

public class TCPClient { 

private static final String TAG = "TCPClient"; 
private final Handler mHandler; 


private String ipNumber; 
BufferedReader in; 
PrintWriter out; 
private OnMessageReceived mMessageListener = null; 
private boolean mRun = false; 
private String serverMessage,command; 

public TCPClient(Handler mHandler, String command, String ipNumber, OnMessageReceived listener) { 
    mMessageListener = listener; 
    this.ipNumber = ipNumber; 
    this.command = command; 
    this.mHandler = mHandler; 
} 

public void sendMessage(String message){ 
    if (out != null && !out.checkError()) { 
     out.println(message); 
     out.flush(); 
     mHandler.obtainMessage(MainActivity.SENDING); 
     Log.d(TAG, "Sent Message: " + message); 

    } 
} 


public void stopClient(){ 
    mRun = false; 

} 

public void run() { 

    mRun = true; 


    try { 
     //here you must put your computer's IP address. 
     InetAddress serverAddr = InetAddress.getByName(ipNumber); 

     Log.d(TAG, "C: Connecting..."); 

     //create a socket to make the connection with the server 
     Socket socket = new Socket(serverAddr, 4444); 


     try { 

      //send the message to the server 
      out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 

      Log.d("TCP Client", "C: Sent."); 

      Log.d("TCP Client", "C: Done."); 

      //receive the message which the server sends back 
      in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      this.sendMessage(command); 
      //in this while the client listens for the messages sent by the server 
      while (mRun) { 
       serverMessage = in.readLine(); 


       Log.d("TCP", "S: Received Message: '" + serverMessage + "'"); 
       if (serverMessage != null && mMessageListener != null) { 
        //call the method messageReceived from MyActivity class 
        mMessageListener.messageReceived(serverMessage); 

       } 
       serverMessage = null; 

      } 

      Log.d("TCP", "S: Received Message: '" + serverMessage + "'"); 

     } catch (Exception e) { 

      Log.d("TCP", "S: Error", e); 

     } finally { 
      //the socket must be closed. It is not possible to reconnect to this socket 
      // after it is closed, which means a new socket instance has to be created. 
      out.flush(); 
      out.close(); 
      in.close(); 
      socket.close(); 
      Log.d("TCP", "Socket Closed"); 
     } 

    } catch (Exception e) { 

     Log.d("TCP", "C: Error", e); 

    } 

} 

//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity 
//class at on asynckTask doInBackground 
public interface OnMessageReceived { 
    public void messageReceived(String message); 
} 

}

這裏我的AsyncTask啓動和處理連接:

public class ShutdownAsyncTask extends AsyncTask<String, String, TCPClient> { 

private static final String COMMAND = "shutdown -s"; 
private TCPClient tcpClient; 
private Handler mHandler; 
private static final String TAG = "ShutdownAsyncTask"; 

public ShutdownAsyncTask(Handler mHandler){ 
    this.mHandler = mHandler; 
} 

@Override 
protected TCPClient doInBackground(String... params) { 
    Log.d(TAG, "In do in background"); 

    try{ 
     tcpClient = new TCPClient(mHandler,COMMAND, new IpGetter().getIp(), new TCPClient.OnMessageReceived() { 
      @Override 
      public void messageReceived(String message) { 
       publishProgress(message); 
      } 
     }); 
    }catch (NullPointerException e){ 
     Log.d(TAG, "Caught null pointer exception"); 
     e.printStackTrace(); 
    } 
    tcpClient.run(); 
    return null; 
} 

@Override 
protected void onProgressUpdate(String... values) { 
    super.onProgressUpdate(values); 
    Log.d(TAG, "In progress update, values: " + values); 
    if(values.equals("connected")){ 
     tcpClient.sendMessage(COMMAND); 
     tcpClient.stopClient(); 
     mHandler.obtainMessage(MainActivity.SHUTDOWN); 
    }else{ 
     tcpClient.sendMessage("wrong"); 
     mHandler.obtainMessage(MainActivity.ERROR); 
     tcpClient.stopClient(); 
    } 
} 

@Override 
protected void onPostExecute(TCPClient result){ 
    super.onPostExecute(result); 
    Log.d(TAG, "In on post execute"); 
} 

}

在這裏,我有了方法getIp IpGetter類()用於從本地網絡動態獲取IP:

public class IpGetter { 

private static Future<String> portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) { 
    Log.d("IpGetter", "In portIsOpen"); 
    return es.submit(new Callable<String>() { 
     @Override public String call() { 
      try { 
       Socket socket = new Socket(); 
       socket.connect(new InetSocketAddress(ip, port), timeout); 
       socket.close(); 
       Log.d("portIsOpen", "ip: " + ip); 
       return ip; 
      } catch (Exception ex) { 
       return null; 

      } 
     } 
    }); 
} 

public static String getIp(){ 
    final ExecutorService es = Executors.newFixedThreadPool(20); 

    final int timeout = 200; 
    final int port = 4444; 
    final List<Future<String>> futures = new ArrayList<Future<String>>(); 
    for (int i = 0; i <= 255; i++) { 
     String ip = "192.168.1."+i; 
     futures.add(portIsOpen(es, ip, port, timeout)); 
    } 
    es.shutdown(); 

    for (final Future<String> f : futures) { 
     try { 
      if (f.get() != null) { 
       Log.d("F get", f.get()); 
       return f.get(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } catch (ExecutionException e) { 
      e.printStackTrace(); 
     } 
    } 
    return null; 
} 

}

在服務器端一切都很好。

try{ 
     tcpClient = new TCPClient(mHandler,COMMAND, "192.168.1.103",... 

要:

try{ 
     tcpClient = new TCPClient(mHandler,COMMAND, new IpGetter().getIp(),.... 

有誰知道如何管理它,當我改變了一切正在發生變化?感謝幫助。

回答

0

好吧,我解決了它。事實證明,我打開IpGetter套接字後沒有重啓服務器。現在我已經完成了!

相關問題