服务器似乎没有收到客户端消息ANDROID

时间:2014-05-25 07:59:03

标签: android sockets client

我正在开发一个聊天客户端应用程序,我已经创建了一个服务器。我设法使客户端连接到服务器,但是当我向服务器发送消息时,服务器没有任何反应。

以下是我的服务器代码中无法正常工作的部分

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();
    }

    }

我通过单击按钮从客户端发送消息然后转到SendMessage类,并将消息发送到服务器,通常服务器应该在循环中接收我的消息&#34; while(true)。 ..&#34;并根据我已实施的协议发回回复。

我真的不知道出了什么问题。如果您知道如何解决此问题或有一些解决方案,请告诉我!如果您想了解更多细节,请问我! :)

非常感谢!

编辑:

我在这里实现了我的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中,它只显示&#34; beforeconvert&#34;。我真的不知道问题是什么? while((line = reader.readLine())!= null)肯定是问题所在。当我在eclipse中逐步使用调试器时,它会在此行停止,甚至不会进入循环。

编辑:我真的不知道为什么,但是当我在运行我的应用程序时退出模拟器时,它会显示所有内容。

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

1 个答案:

答案 0 :(得分:0)

当您将数据写入输出流时,您需要刷新

this.out.flush();

我认为这就是为什么不发送和接收数据

希望有所帮助。

编辑:

让我试着解释一般的想法..

当你打开一个插座时,你可以连接另一个机器人。

所以

in.available(); 

socket.accpet();

应该工作..一旦你写入输出流你必须刷新才能看到数据(或关闭,我认为它在关闭之前刷新)。

无论如何我附上一个例子的链接..你应该尝试这个,或者看看你有问题的部分..

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