2012-02-16 5 views
1

인스턴트 메신저 응용 프로그램을 작성하는 TCP 서버에 읽기/쓰기 문제가 있습니다. 최근 스레드에서 대신 서비스를 사용하도록 제안되었지만 asyncTask를 제안한 학교 프로젝트이므로이를 위해 사용할 수도 있습니다.안드로이드 asynctask 소켓에서 읽기

ive 클래스는 내 액티비티 클래스와 비동기식이므로 아무것도 흥미롭지는 않지만 활동중인 문자열을 보내는 것은 비동기식으로 진행됩니다. 내가 알고

class ServerTask extends AsyncTask<Void, Void, Void>{ 

     public static String ip = "10.0.2.2"; 
     public static int port = 2002; 
     Socket socket; 
     public DataInputStream dis; 
     public DataOutputStream dos; 
     public String message; 

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

      try { 
       socket = new Socket(ip, port); 
       dis = new DataInputStream(socket.getInputStream()); 
       dos = new DataOutputStream(socket.getOutputStream()); 

      } catch (Exception e) { 
       Log.i("AsyncTank", "Cannot create Socket"); 
      } 
      while(socket.isConnected()){ 
       read();      
        } 
       } 

      } 
      return null; 
     } 

     public void write(String message) { 
      try { 
       if (socket.isConnected()){ 
        dos.writeUTF(message); 
        dos.flush(); 
       } else { 
        Log.i("AsynkTask", "Socket appears to be closed"); 
       } 
      } catch (Exception e) { 
       Log.i("AsynkTask", "Writing failed"); 
      } 
     } 

     public String read() { 
      try { 
       if (socket.isConnected()) { 
        message = dis.readLine(); 
       } else { 
        Log.i("AsyncTask", "Cannot read"); 
       } 
      } catch (Exception e) { 
       Log.i("AsyncTask", "Cannot read from stream"); 
      } 
      return message; 
     } 
    } 

것들, 서버는 메시지를받을 않지만 내가 그 메신저가 모두 한 줄 이후로 보이게 새로운 라인 또는 무언가를 밀어하지 믿고 날 리드 서버를 다시 시작할 때까지 업데이트가 나던 그 폐쇄. 그러나 이것은 또한 메신저가 책임질 수없는 서버가 될 수도 있습니다.

그러나 읽기 부분은 작동하지 않으려 고합니다. 메소드를 호출하여 서버 sockt에 지속적으로 응답하고 응답하게하는 방법은 확실하지 않습니다. doInBackGround의 반환 전에 스레드를 만들려고했지만 응용 프로그램이 몇 초 동안 작동하지 않습니다. 메모리 부족으로 인해 강제 종료됩니까? 끊임없이 계속 듣기 위해 실이 필요합니까?

당신이 짐작할 수 있듯이이 요점은 read 메소드가 결국 내 액티비티 클래스의 textView를 업데이트하도록되어 있기 때문입니다. send 메서드는 "작동 중"이지만 이전에 서버가 펑키 한 업무를 수행하고 있다고 말했을 수도 있지만 그렇게 할 수는 없습니다.

또 하나, 내가 가진 것처럼 읽을 수도 있고, 서버가 데이터를 보낸 다음 메서드를 호출 할 때 반응해야 할 수도 있습니다.

편집 지금 doInBackGround을 읽기 부분, 또는 그 이상이어야 일부를 이동 한 지금은 이제

를 서버에 printline를 하드에 변화와 함께

이 날이 읽어했다 클라이언트의 라인 그래서 지금은 realtively 좋은 일을 짐작하고 있습니다.

어째서? 그것은이 코드를 완전히 망각하고 다른 방법으로 수행해야합니까? 내 기능을 갖추고 있지만 말을 잘하는 법을 배우는 것이 나쁘지는 않습니다. :).

답변

0

AsyncTask의 doInBackground() 메소드에서 쓰기와 읽기 모두를 수행해야합니다. 둘 다 시간이 걸리고 기본 (UI) 스레드를 차단할 수 있기 때문입니다. 위의 write() 메서드를 어떻게 호출하는지 알지 못하지만이 question that might be related을 살펴볼 수도 있습니다.

+0

내 Main 클래스에서 ServerTask 클래스를 인스턴스화하고 단순히 serverTask.write (tbMessage.getText(). toString());를 수행합니다. 비동기 작업에 대해 생각하고 있지만 비동기 를 작성하지 않고 params [0]를 작성하지 않고 write를 호출하는 방법을 알지 못했지만 매번 serverTask.execute (텍스트)를 써야 함을 의미합니다. 그리고 매번 새로운 연결을 만드는 것? – Gvs

+0

한 가지 더, doInBackGround 스트림을 열어 스트림에 쓸 때 쓰지 않습니다. – Gvs

+0

AsyncTasks에 읽기/쓰기를 넣고 스트림을 매개 변수로 전달할 수 있습니다. 위의 코드에서 doInBackground() 메서드의 코드는 백그라운드에서 실행되고 doInBackground()에서 호출 한 이후 read()를 호출합니다. write()는 적어도 포함 된 코드에서 나온 것 같지 않습니다. – jengelsma