2014-05-25 143 views
0

我正在聊天客戶端應用程序,我已經做了一個服務器。我設法讓客戶端連接到服務器,但是當我向服務器發送消息時,服務器沒有任何反應。服務器似乎沒有收到客戶端消息ANDROID

這裏是我的服務器的代碼不工作

class ClientConnect implements Runnable { 


private DataInputStream in = null; 
private DataOutputStream out = null; 
Socket client; 

ClientConnect(Socket client) { 

    try { 
     this.client = client; 
     /* obtain an input stream to this client ... */ 
     in = new DataInputStream (client.getInputStream()); 

     /* ... and an output stream to the same client */ 
     setOut(new DataOutputStream (client.getOutputStream())); 

    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public void run() { 

    String msg, response; 
    ChatServerProtocol protocol = new ChatServerProtocol(this); 

    try { 

     while (true) { 

      if (in.available() > 0){ 
       msg = in.readUTF(); 
       response = protocol.process(msg); 
       getOut().writeBytes("SERVER: " + response); 
      } 
     } 
    } catch (IOException e) { 
     System.err.println(e); 
    } finally { 

     // The connection is closed for one reason or another  
     try { 
      client.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

public void sendMsg(String msg) { 
    try { 
     getOut().writeBytes(msg); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

public DataOutputStream getOut() { 
    return out; 
} 

public void setOut(DataOutputStream out) { 
    this.out = out; 
} 
} 

的一部分,這裏是客戶端:

@Override 
    public void onClick(View v) { 
    // TODO Auto-generated method stub 
    String response = null; 

    EditText nicknameField = (EditText)findViewById(R.id.nicknameField); 
    EditText passwordField = (EditText)findViewById(R.id.passwordField); 

    nickname = nicknameField.getText().toString(); 
    password = passwordField.getText().toString(); 

    switch(v.getId()){ 
     case R.id.signin:   

      new SendMessage(this).execute("SIGNUP " + nickname + " " + password); 

      break; 
     case R.id.signup: 

      new SendMessage(this).execute("SIGNUP " + nickname + " " + password); 

      break; 
    } 
} 

private String onPostExecuteSendMessage() { 
    return null; 
} 

public void showMessage(String response) { 

    Builder builder = new AlertDialog.Builder(this); 
    builder.setMessage(response); 
    AlertDialog dialog = builder.create(); 
    dialog.show(); 

} 

public void getClientSocket(Socket client) { 

    this.client = client; 
    try { 
     out = new DataOutputStream (client.getOutputStream()); 
     in = new DataInputStream (client.getInputStream()); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 


} 

public DataOutputStream getOut() { 
    // TODO Auto-generated method stub 
    return this.out; 
} 

public DataInputStream getIn() { 
    // TODO Auto-generated method stub 
    return this.in; 
} 

public void goMenuChat() { 
    // TODO Auto-generated method stub 
    Intent intent = new Intent(this, MenuChatActivity.class); 
    startActivity(intent); 
} 

} 

而且我用的AsyncTask從客戶端發送消息:

package client.chatclient; 

    import java.io.BufferedReader; 
    import java.io.DataInputStream; 
    import java.io.DataOutputStream; 
    import java.io.IOException; 
    import java.io.InputStream; 
    import java.io.InputStreamReader; 
    import java.lang.ref.WeakReference; 
    import android.os.AsyncTask; 

    public class SendMessage extends AsyncTask<String, String, String> { 


    private static final String msg_OK = "OK"; 
    private static final String msg_NICK_IN_USE = "NICK IN USE"; 
    private static final String msg_UNKNOWN_CMD = "UNKNOWN CMD"; 
    private static final String msg_INVALID = "INVALID COMMAND"; 
    private static final String msg_SEND_FAILED = "FAILED TO SEND"; 
    private static final String msg_INCORRECT_IDS = "INCORRECT IDS"; 
    private static final String msg_DISCONNECT = "DISCONNECT"; 

    private WeakReference<MainActivity> activity; 
    private String message; 
    private String response = ""; 
    private DataOutputStream out; 
    private DataInputStream in; 

    public SendMessage(MainActivity act){ 
     super(); 
     activity = new WeakReference<MainActivity>(act); 

    } 

    protected String doInBackground(String... message) { 
     this.message = message[0]; 
     this.out = activity.get().getOut(); 
     this.in = activity.get().getIn(); 
     try { 
      out.writeBytes(this.message); 
     } catch (IOException e) { 
     // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


     response = convertStreamToString(this.in); 

     return response; 
    } 



    protected void onPostExecute(String response) { 

     if ((response == msg_INCORRECT_IDS) || (response == msg_NICK_IN_USE)){ 
      activity.get().showMessage(response); 
     } 
     else if (response == msg_OK){ 
      activity.get().goMenuChat(); 

     } 

    } 

    private static String convertStreamToString(DataInputStream in) { 
     /* 
     * To convert the InputStream to String we use the 
     * BufferedReader.readLine() method. We iterate until the BufferedReader 
     * return null which means there's no more data to read. Each line will 
     * appended to a StringBuilder and returned as String. 
     */  

     BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
     StringBuilder sb = new StringBuilder(); 
     String line = null; 
     try { 
      while ((line = reader.readLine()) != null) { 
       sb.append(line + "\n"); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return sb.toString(); 
    } 

    } 

我通過點擊一個按鈕從客戶端發送消息到SendMe ssage類,並且將消息發送到服務器,通常服務器應該在循環收到我的消息「而(真)...」,併發送回照我已經實現了協議的響應。

我真的不知道什麼是錯。如果你知道如何解決這個問題或有一些解決方案,請告訴我!如果你想要更多的細節,請問我! :)

非常感謝您!

編輯:

我這裏實例化我ClientConnect

public class ChatServer { 


private static int port = 8080; 

public static void main (String[] args) throws IOException { 

    ServerSocket server = new ServerSocket(port); /* start listening on the port */ 
    System.out.println("Listening on "+ server); 

    Socket client = null; 

    while(true) { 
     try { 
      client = server.accept(); 
      System.out.println("Connection from " + client); 
      /* start a new thread to handle this client */ 
      Thread t = new Thread(new ClientConnect(client)); 
      t.start(); 
     } catch (IOException e) { 

      System.err.println("Accept failed."); 
      System.err.println(e); 
      System.exit(1); 
      server.close(); 
     } 
    } 


} 

}

編輯:我發現了問題的所在。我把一些log()語句如你所說

log.d(null,"beforeconvert") 
    try { 
     log.d(null,"convert") 
     while ((line = reader.readLine()) != null) { 
      sb.append(line + "\n"); 
     } 
    } catch (IOException e) { 
     log.d(null,"errorconvert") 
     e.printStackTrace(); 
    } 

然後在logcat中,它只顯示「beforeconvert」。我真的不知道問題是什麼? ,而((行= reader.readLine())!= NULL)無疑是這個問題。當我在日食步驟中使用調試器的步驟,它停在這條線上,甚至不走內環路。

編輯:我真的不知道爲什麼,但是當我跑我的應用程序時退出模擬器,它顯示了一切。

Listening on ServerSocket[addr=0.0.0.0/0.0.0.0,localport=8080] 
Connection from Socket[addr=/127.0.0.1,port=56646,localport=8080] 
client connected 
msg received 
error ! 
SIGNUP Nickname Password 

SIGNUP Nickname Password 

msg converted 
OK 
java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.io.DataInputStream.read(Unknown Source) 
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) 
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
    at sun.nio.cs.StreamDecoder.read(Unknown Source) 
    at java.io.InputStreamReader.read(Unknown Source) 
    at java.io.BufferedReader.fill(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at server.ClientConnect.convertStreamToString(ChatServer.java:357) 
    at server.ClientConnect.run(ChatServer.java:304) 
    at java.lang.Thread.run(Unknown Source) 
java.net.SocketException: Connection reset by peer: socket write error 
+0

添加一些日誌()語句,所以你/我們可以看到服務器到達多遠。把它們也放在catch塊中。顯示你如何實例化/調用ClientConnect。 – greenapps

+0

我的問題可能來自while((line = reader.readLine())!= null){我是否正確使用readLine方法? – nytochin

+0

你的服務器沒有發送任何東西。所以你的客戶沒有什麼可讀的。 – greenapps

回答

0

當你在端將數據寫入到輸出流就需要刷新

this.out.flush();

我想這就是爲什麼數據不發送和接收

希望有所幫助。

編輯:

讓我嘗試在一般的想法來解釋..

當你打開一個插座,你必須另外machince的連接。

所以

in.available(); 

socket.accpet(); 

應該工作..一旦你寫入的OutputStream您必須看到的數據刷新(或接近,我認爲它才衝關閉)。

反正我附上一個鏈接到一個例子。您應該嘗試這一個,還是看你的部分有問題..

http://examples.javacodegeeks.com/android/core/socket-core/android-socket-example/

+0

非常感謝您的回覆,我在兩臺服務器上都添加了這個功能,但它無效。我的服務器實際上收到消息,但卡在這一行** while((line = reader.readLine())!= null)**由於某種原因。 – nytochin

+0

好吧,你仍然需要在寫入後使用flush。After你寫的刷新將是發送你寫的字節的動作.. 發送後你正在等待inputStream寫給你... 因爲你永遠不會使用刷新它永遠不會發送數據,這就是爲什麼它正在等待..因爲它沒有得到傳輸。 不知道你的服務器如何獲得數據..這聽起來很奇怪..沖洗是必須使用..也建議關閉輸入/輸出流 – Aviad

+0

好的沖洗:)我的服務器接收數據在這個循環** while(true){if(in.available()> 0)** ...它在if語句中輸入時點擊按鈕,所以它一直工作到那裏。關閉進出流是強制性的嗎?因爲我想多次使用它們,因爲它是一個聊天應用程序。 – nytochin

相關問題