2014-05-25 145 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

相关问题