【问题标题】:Server doesn't seem to receive Client message ANDROID服务器似乎没有收到客户端消息 ANDROID
【发布时间】:2014-05-25 07:59:03
【问题描述】:

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

这是我的服务器不工作的部分代码

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 类,并将消息发送到服务器,通常服务器应该在循环“while (true)...”中接收我的消息并根据我实现的协议发回响应。

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

非常感谢!

编辑:

我在这里实例化了我的 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”。我真的不知道问题是什么? 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

【问题讨论】:

  • 添加一些 Log() 语句,以便您/我们可以看到服务器走了多远。将它们也放在捕获块中。展示您如何实例化/调用 ClientConnect。
  • 我的问题可能来自 while ((line = reader.readLine()) != null) { 我是否正确使用了 readLine 方法?
  • 您的服务器没有发送任何内容。因此,您的客户无需阅读任何内容。

标签: android sockets client


【解决方案1】:

当你最终将数据写入输出流时,你需要刷新

this.out.flush();

我认为这就是为什么没有发送和接收数据的原因

希望对您有所帮助。

编辑:

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

当您打开一个套接字时,您将连接到另一台机器。

所以

in.available(); 

socket.accpet();

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

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

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

【讨论】:

  • 感谢您的回复,我在我的两个服务器上都添加了它,但它不起作用。我的服务器实际上收到了消息,但由于某种原因,while ((line = reader.readLine()) != null) 卡在这一行......
  • 好吧,你还是需要在写完之后使用flush..写完之后flush将是发送你写的字节的动作..发送之后你正在等待inputStream写给你.. .因为你从不使用刷新它永远不会发送数据,这就是它等待的原因..因为它没有得到传输。不知道你的服务器是如何获取数据的..这听起来很奇怪..必须使用刷新..并且还建议关闭输入/输出输出流
  • OK 刷新 :) 我的服务器在这个循环中接收数据 while (true) { if (in.available() > 0)... 它进入当我点击按钮时的 if 语句,所以它一直有效。是否必须关闭和关闭流?因为它是一个聊天应用程序,所以我想多次使用它们。
  • 但是你能看到这行吗?它接收字符串? msg = in.readUTF(); response = protocol.process(msg);
  • 不。我用 convertStreamToString(in) 替换了 in.readUTF()。我看不到消息和响应。我刚刚在我的帖子中添加了一些内容,请检查。
猜你喜欢
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
相关资源
最近更新 更多