2015-08-14 57 views
0

我在android中實現套接字編程。我成功從客戶端獲取數據並將其顯示到服務器。如何從Android套接字服務器獲取多個郵件

的的AsyncTask如下:

public class MyClientTask extends AsyncTask<Void, Void, Void> { 

    String dstAddress; 
    int dstPort; 
    String response = ""; 

    MyClientTask(String addr, int port){ 
    dstAddress = addr; 
    dstPort = port; 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 

    Socket socket = null; 

    try { 
    socket = new Socket(dstAddress, dstPort); 

    ByteArrayOutputStream byteArrayOutputStream = 
        new ByteArrayOutputStream(1024); 
    byte[] buffer = new byte[1024]; 

    int bytesRead; 
    InputStream inputStream = socket.getInputStream(); 

    /* 
    * notice: 
    * inputStream.read() will block if no data return 
    */ 
      while ((bytesRead = inputStream.read(buffer)) != -1){ 
       byteArrayOutputStream.write(buffer, 0, bytesRead); 
       response += byteArrayOutputStream.toString("UTF-8"); 
      } 

    } catch (UnknownHostException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    response = "UnknownHostException: " + e.toString(); 
    } catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
    response = "IOException: " + e.toString(); 
    }finally{ 
    if(socket != null){ 
    try { 
     socket.close(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 
    } 
    return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
    textResponse.setText(response); 
    super.onPostExecute(result); 
    } 

} 

} 

上面的代碼從服務器中獲取數據並將其寫入到文本視圖。我想使用相同的套接字從服務器多次獲取數據,除非單擊某個特定的按鈕。但是,在doInBackground中,我們不能使用任何UI組件。我想改變下列組件,這樣我可以從服務器收到多個數據:

socket = new Socket(dstAddress, dstPort); 

     ByteArrayOutputStream byteArrayOutputStream = 
         new ByteArrayOutputStream(1024); 
     byte[] buffer = new byte[1024]; 

     int bytesRead; 
     InputStream inputStream = socket.getInputStream(); 

     /* 
     * notice: 
     * inputStream.read() will block if no data return 
     */ 
       while ((bytesRead = inputStream.read(buffer)) != -1){ 
        byteArrayOutputStream.write(buffer, 0, bytesRead); 
        response += byteArrayOutputStream.toString("UTF-8"); 
       } 

我試圖用

onProgressUpdate

,但它也不能工作。請幫我解決這個問題。

編輯1:客戶端的主要活動:

package com.example.shiza.client; 

import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 

import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.Socket; 

public class MainActivity extends AppCompatActivity { 
    private static final String TAG = "CLIENT_MESSAGE"; 
    EditText ip_address; 
    EditText port_number; 
    EditText message_client; 
    Button button_send; 
    Button button_cancel; 

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

    } 

    public void connect(View view) { 
//  ip_address = (EditText) findViewById(R.id.ip_address); 
//  ip_address.setText("192.168.9.100"); 
//  port_number = (EditText) findViewById(R.id.port_number); 
//  port_number.setText("8080"); 
     message_client = (EditText) findViewById(R.id.message_client); 
     button_send = (Button)findViewById(R.id.button_send); 
     button_cancel = (Button)findViewById(R.id.button_cancel); 
     Log.d(TAG, "connecting to the server."); 
//  new ConnectToServer(ip_address.getText().toString(), port_number.getText().toString(), message_client,button_send,button_cancel).execute(); 
     new ConnectToServer("192.168.9.100","8080", message_client,button_send,button_cancel).execute(); 

    } 
} 

class ConnectToServer extends AsyncTask<Void, DataOutputStream, Void> { 
    private static final String TAG = "CLIENT_MESSAGE"; 
    String ip_address; 
    int port_number; 
    EditText message_client; 
    Button button_send; 
    Button button_cancel; 
    boolean send = false; 
    boolean cancel = false; 

    public ConnectToServer(String ip_address, String port_number, EditText message_client,Button button_send,Button button_cancel) { 
     this.ip_address = ip_address; 
     this.port_number = Integer.parseInt(port_number); 
     this.message_client = message_client; 
     this.button_cancel = button_cancel; 
     this.button_send = button_send; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 

     try { 
      Socket socket = new Socket(ip_address, port_number); 

      if (LoggerConfig.TAG) { 
       Log.d(TAG, "the socket is created at " + ip_address); 
      } 

      DataOutputStream output = new DataOutputStream(socket.getOutputStream()); 
      while (!cancel) 
       publishProgress(output); 
//   output.writeUTF("Hello from string"); 
      if (LoggerConfig.TAG) { 
       Log.d(TAG, "I have written and closed the loop."); 
      } 
      socket.close(); 
     } catch (IOException e) { 
      if (LoggerConfig.TAG) { 
       Log.d(TAG, "Could not connect."); 
      } 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    @Override 
    protected void onProgressUpdate(DataOutputStream... values) { 
     super.onProgressUpdate(values); 

     button_send.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       send = true; 
      } 
     }); 

     button_cancel.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 

       cancel = true; 
      } 
     }); 

     Log.d(TAG, "I am in onProgressUpdate"); 

      if (send) 
      { 
       try { 
        values[0].writeUTF(message_client.getText().toString()); 
        Log.d(TAG, "I am in onProgressUpdate try."); 

       } catch (IOException e) { 
        e.printStackTrace(); 
        Log.d(TAG, "I am in onProgressUpdate catch."); 

       } 

       send = false; 
      } 

    } 
} 

服務器的主要活動:

package com.example.shiza.server; 

import android.content.Context; 
import android.net.wifi.WifiManager; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.text.format.Formatter; 
import android.util.Log; 
import android.view.View; 
import android.widget.TextView; 
import android.widget.Toast; 

import java.io.DataInputStream; 
import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 


public class MainActivity extends AppCompatActivity { 
    TextView ip_address; 
    TextView client_message; 
    TextView server_status; 
    TextView show_client_message; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     ip_address = (TextView) findViewById(R.id.ip_address); 
     client_message = (TextView) findViewById(R.id.get_client_message); 
     server_status = (TextView) findViewById(R.id.server_status); 
     show_client_message = (TextView) findViewById(R.id.show_client_message); 


     WifiManager wm = (WifiManager) getSystemService(WIFI_SERVICE); 
     String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress()); 

     ip_address.setText(ip); 

//  Making a server socket here 


    } 

    public void startServer(View view) { 
     GetFromClient getFromClient = new GetFromClient(this,server_status,show_client_message); 
     getFromClient.execute(); 
    } 

} 

class GetFromClient extends AsyncTask<Void, String, Void> { 
    Context context; 
    TextView server_status; 
    TextView show_client_message; 
    String TAG = "SERVER_MESSAGE"; 
    String inputFromClient = null; 

    public GetFromClient(Context context,TextView server_status,TextView show_client_message) { 
     this.context = context; 
     this.server_status = server_status; 
     this.show_client_message = show_client_message; 
    } 

    @Override 
    protected Void doInBackground(Void... params) { 
     Socket socket; 
     try { 
      ServerSocket serverSocket = new ServerSocket(8080); 
      Log.d(TAG, "Server Socket is starting...."); 
//   server_status.setText("The server is running"); 


      publishProgress("okay"); 
      socket = serverSocket.accept(); 

      DataInputStream input = new DataInputStream(socket.getInputStream()); 

//   Calling the second background task for handling input from server 

//   Log.d(TAG, "Server Socket is started...."); 
      do 
      { 
       try { 
        Thread.sleep(500); 
       } catch (InterruptedException ie) { 
        ie.printStackTrace(); 
       } 
       inputFromClient = input.readUTF(); 
       publishProgress(inputFromClient); 
      } 
      while (inputFromClient != "bye"); 

//   publishProgress(2); 
      socket.close(); 

     } catch (IOException e) { 
      Log.d(TAG, "I am in catch."); 
      e.printStackTrace(); 

     } 

     return null; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     Log.d(TAG, "I am in onProgress update."); 
     if (values[0].equals("okay")) 
     { 
      server_status.setText("Server has been started"); 
      server_status.setTextColor(context.getResources().getColor(R.color.green)); 
     } 
     else 
     { 
      show_client_message.setText(values[0]); 
     } 


    } 

    protected void onPostExecute(Void inputFromClient) 
    { 
     Log.d(TAG, "I am in onPostExecute."); 

     server_status.setText("Server is not running"); 
     server_status.setTextColor(context.getResources().getColor(R.color.red)); 
    } 
} 

我能夠做到的消息,但下面的循環塊的一切:

do 
       { 
        try { 
         Thread.sleep(500); 
        } catch (InterruptedException ie) { 
         ie.printStackTrace(); 
        } 
        inputFromClient = input.readUTF(); 
        publishProgress(inputFromClient); 
       } 
       while (inputFromClient != "bye"); 
+0

'我成功從客戶端獲取數據並將其顯示到服務器。令人困惑的是:'上面的代碼從服務器獲取數據並將其寫入文本視圖。 '。 ????? – greenapps

+0

'試圖使用 onProgressUpdate 但它也沒有工作。 '。那麼應該工作。請添加該代碼。 – greenapps

+0

@greenapps我只是粘貼...我只是混合客戶端/服務器..我認爲沒關係... – learner

回答

0

您可以使用RunUiThread在doInBackground方法中更新TextView。從服務器收到數據後,只需撥打電話

runOnUiThread(new Runnable() { 
         @Override 
         public void run() { 
          //here you update the views 
         } 
        }); 
+0

謝謝你的回覆。讓我檢查一下。 – learner

+0

AsyncTask類具有一個帶有onProgressUpdate的publishProgress。 – greenapps

相關問題