4

到目前为止,我能够在一个 android 设备(wifi 网络共享/热点)上启动一个服务器,并让客户端(另一个 android)连接并向服务器发送消息。然后服务器回复了。我意识到我需要一种方法来保持服​​务器监听客户端,即使聊天应用程序没有运行。客户端应该能够发送消息并且服务器应该接收到这个。我应该使用 Service 还是 IntentService 来归档这个?我不能从 AsyncTask & Service 扩展...如何实现这个?一些示例代码会很棒。

这是我的服务器的样子:

public class Server extends AsyncTask<Integer, Void, Socket> {

    private ServerSocket serverSocket;
    private TextView textView;
    private String incomingMsg;
    private String outgoingMsg;

    public Server(TextView textView) {
        this.textView = textView;
    }

    public void closeServer() {
        try {
            serverSocket.close();
        } catch (IOException e) {
            Log.d("Server", "Closung the server caused a problem");
            e.printStackTrace();
        }       
    }


    @Override
    protected Socket doInBackground(Integer... params) {

        try {
            serverSocket = new ServerSocket(params[0]);       

            //accept connections
            Socket socket = serverSocket.accept();

            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            incomingMsg = in.readLine() + System.getProperty("line.separator");

            //send a message
            outgoingMsg = "You are connected to the Server" + System.getProperty("line.separator");
            out.write(outgoingMsg);
            out.flush();

            return socket;


        } catch (InterruptedIOException e) {
            //if timeout occurs
            e.printStackTrace();

        } catch (IOException e) {
            e.printStackTrace();

        } 
//      finally {
//          if (serverSocket != null) {
//              try {
//                  serverSocket.close();
//              } catch (IOException e) {
//                  e.printStackTrace();
//              }
//          }
//      }

        return null;
    }


    protected void onPostExecute(Socket socket) {

        if(socket != null) {
            try {

                Log.i("Server", "Server received: " + incomingMsg);
                textView.setText("Server received: " + incomingMsg + "\n");

                textView.append("Server sent: " + outgoingMsg + "\n");
                Log.i("Server", "Server sent: " + outgoingMsg);

                socket.close();

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

        } else {
            Log.d("Server", "Can't communicate with the client!");
        }
    }
}

这是我的客户:

public class Client extends AsyncTask<Integer, Void, Socket> {

    private WifiManager wifi;
    private Context context;
    private String outMsg;
    private String inMsg;

    public Client(Context context, WifiManager wifiManager) {
        this.context = context;
        this.wifi = wifiManager;
    }

    @Override
    protected Socket doInBackground(Integer... params) {

        try {

            String gateway = intToIp(wifi.getDhcpInfo().gateway);
            Socket socket = new Socket(gateway, params[0]);

            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            String ipAdress = intToIp(wifi.getConnectionInfo().getIpAddress());

            outMsg = ", Client " + ipAdress +" is connecting!" + System.getProperty("line.separator"); 
            out.write(outMsg);
            out.flush();

            //accept server response
            inMsg = in.readLine() + System.getProperty("line.separator");

            return socket;

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null; 
    }


    public String intToIp(int addr) {
        return  ((addr & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF) + "." + 
                ((addr >>>= 8) & 0xFF));
    }


    protected void onPostExecute(Socket socket) {

        if(socket != null) {

            Log.i("Client", "Client sent: " + outMsg);
            Toast.makeText(context, "\nClient sent: " + outMsg + "\n", Toast.LENGTH_LONG).show();

            Log.i("Client", "Client received: " + inMsg);
            Toast.makeText(context, "Client received: " + inMsg + "\n", Toast.LENGTH_LONG).show();

        } else {
            Log.d("Client", "Can't connect to server!");
            Toast.makeText(context, "Can't connect to server!", Toast.LENGTH_LONG).show();
        }           
    }
}

如何从服务器中创建服务?客户端也应该是服务吗?

4

1 回答 1

3

使用服务但忘记 AsyncTask。让您的服务启动您的通用线程 ( https://developer.android.com/reference/java/lang/Thread.html ) 并设置您的套接字 + 侦听器。该服务甚至还可以处理消息的发送(通过以下链接中涵盖的众多选项之一)。

不要忘记正确清理服务的 onDestroy() 中的线程。

另请注意,如果您希望应用程序继续接收来自其他客户端的消息,则需要确保服务被强制进入前台(请参阅http://developer.android.com/reference/android/app/Service .html#startForeground(int , android.app.Notification). 然而,这不是万无一失的,你的服务仍然可以被杀死。

这就是为什么人们倾向于使用托管在某个专用盒子上的服务器而不是每个单独的设备...

于 2013-04-17T14:47:49.570 回答