2013-05-26 56 views
0

我想問一些關於android socket的問題。我創建了一個示例應用程序將數據發送到wifly模塊。但是,當我從模塊接收數據我得到套接字超時異常。沒有setSoTimeout應用凍結到inputStream.read。這裏是我的代碼:android socket果凍豆

package com.socket.wiflysocket; 

import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.os.Bundle; 
import android.app.Activity; 
import android.content.Context; 
import android.view.Menu; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.TextView; 

public class MainActivity extends Activity { 

    protected static final String TAG = "WIflySocket"; 

    EditText textOut; 
    TextView textIn; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     textOut = (EditText)findViewById(R.id.textout); 
     Button buttonSend = (Button)findViewById(R.id.send); 
     textIn = (TextView)findViewById(R.id.textin); 
     buttonSend.setOnClickListener(buttonSendOnClickListener); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    Button.OnClickListener buttonSendOnClickListener 
     = new Button.OnClickListener(){ 

      @Override 
      public void onClick(View arg0) { 

       ConnectivityManager connMgr = (ConnectivityManager) 
        getSystemService(Context.CONNECTIVITY_SERVICE); 
       NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 
       if (networkInfo == null || networkInfo.isConnected() == false) { 
        try { 
         throw new Exception("Network is not connected"); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
       else { 
        new SocketThread(textOut.getText().toString()).execute(); 

        textOut.setText(""); 
       } 
      }}; 
} 

和asynkTask:

package com.socket.wiflysocket; 


import java.io.BufferedReader; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 
import java.net.UnknownHostException; 

import android.os.AsyncTask; 
import android.util.Log; 

public class SocketThread extends AsyncTask<String, Void, String>{ 

    private static final String TAG = "SocketAsyncTask"; 

    private static final int BUFFER_SIZE = 8; 

    private String textViewIn; 

    private String output; 

    private Socket socket = null; 

    private PrintWriter outputStream; 

    private InputStreamReader inputStream; 

    public SocketThread(String paramTextViewIn) 
    { 
     this.textViewIn = paramTextViewIn; 
    } 

    @Override 
    protected String doInBackground(String ...views) { 
     Log.d(TAG, "Execute"); 

     DataOutputStream dataOutputStream = null; 
     DataInputStream dataInputStream = null; 

     try { 
      socket = new Socket("1.2.3.4", 2000); 
      socket.setSoTimeout(2000); 

      outputStream = new PrintWriter(new OutputStreamWriter(socket.getOutputStream())); 
      inputStream = new InputStreamReader(socket.getInputStream()); 

      if(socket.isConnected()) { 

       this.sendDataWithString(textViewIn); 

       output = this.receiveDataFromServer(); 
      } 

      this.closeSocket(); 

     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally{ 
      if (socket != null){ 
       try { 
        socket.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      if (dataOutputStream != null){ 
       try { 
        dataOutputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      if (dataInputStream != null){ 
       try { 
        dataInputStream.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 

     return output; 
    } 
    /* 
    // onPostExecute displays the results of the AsyncTask. 
    @Override 
    protected void onPostExecute(String result) { 
     return textViewOut; 
    } 
    */ 

    private void closeSocket() { 
     if (socket != null) { 
      if (socket.isConnected()) { 
       try { 
        inputStream.close(); 
        outputStream.close(); 
        socket.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
    } 

    private void sendDataWithString(String message) { 
     if (message != null) { 
      outputStream.write(message); 
      outputStream.flush(); 
     } 
    } 

    private String receiveDataFromServer() { 
     String message = ""; 
     try { 
      int charsRead = 0; 
      char[] buffer = new char[BUFFER_SIZE]; 

      while ((charsRead = inputStream.read(buffer)) != -1) { 
       message += new String(buffer).substring(0, charsRead); 
      } 

      closeSocket(); 
      return message; 
     } catch (IOException e) { 

      //TODO work around 
      return message; 
      //return "Error receiving response: " + e.getMessage(); 
     } 
    } 

} 

許可,我補充如下:

android.permission.INTERNET; android.permission.ACCESS_NETWORK_STATE

你能否建議我,什麼是錯的,以及如何解決這個問題。 感謝

+0

'inputStream.read()'阻塞,直到輸入數據可用,檢測到文件結尾或引發異常。 – mjosh

+0

當調試應用程序我注意到,但如何獲得數據結束?在調試模式下,我查看發送數據到wifly終端(teraterm)連接到wifly與串行端口。從wifly發送的數據是'Hello',但是當套接字拋出異常時我得到它。我是套接字編程的新手,不知道如何實現正確。 –

回答

1

試試這個 -

BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); 
String userInput;  
    while ((userInput = stdIn.readLine()) != null) { 
     out.println(userInput); 
     System.out.println("echo: " + in.readLine()); 
    } 

或本 -

Reader r = new InputStreamReader(conn.getInputStream()); 
String line; 

StringBuilder sb = new StringBuilder(); 
char[] chars = new char[4*1024]; 
int len; 
while((len = r.read(chars))>=0) { 
    sb.append(chars, 0, len); 
} 

或這一個 -

byte[] resultBuff = new byte[0]; 
byte[] buff = new byte[1024]; 
int k = -1; 
while((k = sock.getInputStream().read(buff, 0, buff.length)) > -1) { 
    byte[] tbuff = new byte[resultBuff.length + k]; 
    System.arraycopy(resultBuff, 0, tbuff, 0, resultBuff.length); bytes 
    System.arraycopy(buff, 0, tbuff, resultBuff.length, k); 
    resultBuff = tbuff; 
} 
+0

我試試這個代碼在所有情況下都購買,線程在讀取方法中凍結,並退出時使用套接字超時豁免。當刪除'setSoTimeout'時,嘗試再次發送數據,它不會從wifly模塊接收,並且讀取後的日誌不會被打印。這是果凍豆的問題嗎?只有解決方法與exeption工作,但我不能檢查響應和檢查響應代碼後發送數據。 –

0

的SocketFactory創建插座您

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.OutputStreamWriter; 

import javax.net.SocketFactory; 

... 

private Socket socket = null; 
public Reader reader = null; 
public Writer writer = null; 

protected void init(String host, int port) throws ClientException { 
    try { 
     socket = SocketFactory.getDefault().createSocket(host, port); 
    } catch (UnknownHostException e) { 
      throw new ClientException(e); 
    } catch (IOException e) { 
     throw new ClientException(e); 
    } 
    initDataManagers(); 
} 
protected void initDataManagers() throws ClientException { 
     try { 
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8")); 
      writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")); 
     } catch (UnsupportedEncodingException e) { 
      throw new ClientException(e); 
     } catch (IOException e) { 
      throw new ClientException(e); 
     } 
}