2012-06-10 10 views
4

Android 앱에 큰 문제가있어 도움을 요청하고 싶습니다.Android에서 두 앱 사이의 소켓 통신

현재 소켓을 사용하여 Android Clietn-Server 앱을 작성 중입니다. 나는 인터넷에서 많은 tutoril을 발견했으며, 그들로부터 프로젝트를위한 기초를 만들었다. 그러나 모든 자습서는 하나의 메시지 전송에만 해당되며 그뿐입니다. 나는 그것들을 더 보낼 필요가있어서 그것을 수정하려고 노력했다.

이 코드는 서버와 클라이언트를 담당합니다. 나머지는 현재로서는 중요하지 않습니다.

서버 : 지금 장치가 올바르게 연결에 대한

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     serverStatus = (TextView) findViewById(R.id.server_status); 
     recivedMsg = (TextView)findViewById(R.id.rec_msg); 

     SERVERIP = getLocalIpAddress(); 

     Thread fst = new Thread(new ServerThread()); 
     fst.start(); 
    } 

    public class ServerThread implements Runnable { 

     public void run() { 
      try { 
       if (SERVERIP != null) { 
        handler.post(new Runnable() { 
         @Override 
         public void run() { 
          serverStatus.setText("Listening on IP: " + SERVERIP); 
         } 
        }); 
        serverSocket = new ServerSocket(SERVERPORT); 
        while (true) { 
         // listen for incoming clients 
         Socket client = serverSocket.accept(); 
         handler.post(new Runnable() { 
          @Override 
          public void run() { 
           serverStatus.setText("Connected." + System.getProperty("line.separator")); 
          } 
         }); 

         try { 
          line = null; 
          while (connected) { 
           BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream())); 
           if((line = in.readLine())!=null) 
           { 
            Log.d("ServerActivity", line); 
            handler.post(new Runnable() { 
             @Override 
             public void run() { 
              if(recivedMsg.equals("CLOSE")) 
              { 
               recivedMsg.append("CLOSE socket"); 
               connected = false; 
              } 
              else 
              { 
               recivedMsg.append("MSG: " + line + System.getProperty("line.separator")); 
              } 
              // do whatever you want to the front end 
              // this is where you can be creative 
             } 
            }); 
           } 
           else 
           { 
            recivedMsg.append("empty" + System.getProperty("line.separator")); 
           } 
          } 
          break; 
         } catch (Exception e) { 
          handler.post(new Runnable() { 
           @Override 
           public void run() { 
            serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones."); 
           } 
          }); 
          e.printStackTrace(); 
         } 
        } 
       } else { 
        handler.post(new Runnable() { 
         @Override 
         public void run() { 
          serverStatus.setText("Couldn't detect internet connection."); 
         } 
        }); 
       } 
      } catch (Exception e) { 
       handler.post(new Runnable() { 
        @Override 
        public void run() { 
         serverStatus.setText("Error"); 
        } 
       }); 
       e.printStackTrace(); 
      } 
     } 
    } 

클라이언트

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

     serverIp = (EditText) findViewById(R.id.server_ip); 
     connectPhones = (Button) findViewById(R.id.connect_phones); 

     sendField = (EditText) findViewById(R.id.send_field); 
     sendMsg = (Button) findViewById(R.id.msg_send); 

     connectPhones.setOnClickListener(connectListener); 
     sendMsg.setOnClickListener(sendMessage); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     try { 
       BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
       //send output msg 
       String outMsg = "CLOSE"; 
       out.write(outMsg); 
       out.flush(); 
       // make sure you close the socket upon exiting 
       s.close(); 
     } catch (IOException e) { 
       e.printStackTrace(); 
     } 
    } 

    private OnClickListener connectListener = new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      serverIpAddress = serverIp.getText().toString(); 
      runTcpConnection(); 
      sendMessageToServer("Msg"); 
     } 
    }; 

    private OnClickListener sendMessage = new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      sendMessageToServer(sendField.getText().toString()); 
     } 
    }; 

    private void runTcpConnection() { 
     try { 
      s = new Socket(serverIpAddress, SERVERPORT); 
      BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
      //send output msg 
      String outMsg = "TCP connecting to " + SERVERPORT + System.getProperty("line.separator"); 
      out.write(outMsg); 
      out.flush(); 
      Log.i("TcpClient", "sent: " + outMsg); 
      SystemClock.sleep(10); 
      s.close(); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    }; 

    public void sendMessageToServer(String str) { 
     try { 
        s = new Socket(serverIpAddress, SERVERPORT); 
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); 
        //send output msg 
        String outMsg = str + System.getProperty("line.separator"); 
        out.write(outMsg); 
        out.flush(); 
        Log.i("TcpClient", "sent: " + outMsg); 
        s.close(); 
       } catch (UnknownHostException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        Log.d("", "hello222"); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
        Log.d("", "hello4333"); 
       } 

      } 

. 또한 그들은 첫 번째 연결 메시지 (OnClickListener connectListener의 메시지)를 전송합니다. 문제는 sendMessageToServer을 사용하여 다른 메시지를 보내려고 할 때 불가능하다는 것입니다. 이러한 메시지는 클라이언트 활동이 소멸 된 후에 만 ​​표시됩니다.

매우 흥미로운 것은 SystemClock.sleep(10); 리스너가 없으면 runTcpConnection()이 이상하게 작동한다는 것입니다. '연결됨'만 서버에 표시됩니다.

정상적으로 메시지를 보내려면 내가해야 할 일을 누군가가 말해 줄 수 있습니까?

편집 : 이것은 내가 발견 한 것들입니다 : 나는 모든 것보다 더 많은 메시지를 보내는 연결에 나는 경우

  • 는 (널) 비어 있고 두 번째 연결 오류가 표시 후를 - 다시 연결하십시오 전화
  • sendMessageToServer에 s.close 줄없이 더 많은 메시지를 보내고있는 경우 하나의 메시지 만 전달됩니다. 그 뒤에는 오류가 표시되지 않습니다. 항상

(이 기능에 더 SystemClock.sleep (10)없는 경우 제외)

  • 메시지 형태 runTcpConnection 쇼 내 오류를 진단하는 사람을 도움이되기를 바랍니다.

  • +0

    이것은 많은 코드와 긴 설명입니다. 작은 예제로 코드의 양을 줄이면, 사람들은 아마 이것에 아주 적용된 질문이 약간의 upvotes를 얻는 해결책을 가지고 있기 때문에, 아마도 도움이 될 것입니다 ... –

    +0

    @KristopherMicinski 나는 이것이 복잡한 질문이지만 나는 동의합니다. 더 이상자를 수 없었습니다. 또한 솔루션에 관해서는 모두 하나의 메시지에만 적용됩니다. – sebap123

    답변

    2

    사용자가 버튼을 클릭 할 때마다 새로운 소켓을 만듭니다. 맞습니까?
    사용자가 연결을 클릭 할 때 한 번만 초기화 한 다음 클릭 이벤트 보내기에 사용하는 것이 좋습니다 (소켓이 새 인스턴스 인 경우 서버에 연결을 끊습니다)
    따라서 을 제거해야합니다. 이 줄 에서 sendMessageToServer :

    s = new Socket(serverIpAddress, SERVERPORT); 
    s.close(); 
    

    runTcpConnection

    s.close(); 
    
    에서이 라인

    서버와 통신하고 싶지 않을 때마다 소켓이 닫혀 야합니다 (onstop은 예제 또는 변경 활동 ...)
    또한 BufferedWriter 인스턴스도 하나만 만들어야합니다.
    도움이 되길 바랍니다.

    +0

    그래서, s.close()는 어디에 있어야합니까? – sebap123

    +0

    @ sebap123 : 답변을 업데이트했습니다. – R4j

    +0

    이것은 좋은 대답입니다. 고맙습니다. 너는 나를 많이 도왔다. – sebap123