使用服务或IntentService的Android客户端/服务器套接字通信

使用服务或IntentService的Android客户端/服务器套接字通信,android,sockets,android-service,Android,Sockets,Android Service,到目前为止,我能够在一台android设备(wifi连接/热点)上启动一台服务器,让客户端(另一台android)连接并向服务器发送消息。服务器随后回复了该请求。我意识到我需要一种方法让服务器监听客户端,即使聊天应用程序没有运行。客户端应该能够发送消息,服务器应该能够接收到消息我应该使用服务还是IntentService来归档这一点?我不能从AsyncTask&Service扩展……如何实现这一点?一些示例代码会很好 这就是我的服务器的外观: public class Server extend

到目前为止,我能够在一台android设备(wifi连接/热点)上启动一台服务器,让客户端(另一台android)连接并向服务器发送消息。服务器随后回复了该请求。我意识到我需要一种方法让服务器监听客户端,即使聊天应用程序没有运行。客户端应该能够发送消息,服务器应该能够接收到消息我应该使用服务还是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!");
        }
    }
}
公共类服务器扩展异步任务{
私有服务器套接字服务器套接字;
私有文本视图文本视图;
私有字符串incomingMsg;
私人字符串输出msg;
公共服务器(文本视图文本视图){
this.textView=textView;
}
公共服务器(){
试一试{
serverSocket.close();
}捕获(IOE异常){
d(“服务器”,“关闭服务器导致问题”);
e、 printStackTrace();
}       
}
@凌驾
受保护的套接字doInBackground(整数…参数){
试一试{
serverSocket=新的serverSocket(参数[0]);
//接受连接
Socket=serverSocket.accept();
BufferedWriter out=新的BufferedWriter(新的OutputStreamWriter(socket.getOutputStream());
BufferedReader in=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
incomingMsg=in.readLine()+System.getProperty(“line.separator”);
//发送消息
outgoingMsg=“您已连接到服务器”+System.getProperty(“line.separator”);
out.write(outgoingMsg);
out.flush();
返回插座;
}捕获(中断异常e){
//如果超时发生
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
} 
//最后{
//if(serverSocket!=null){
//试一试{
//serverSocket.close();
//}捕获(IOE异常){
//e.printStackTrace();
//              }
//          }
//      }
返回null;
}
受保护的void onPostExecute(套接字){
if(套接字!=null){
试一试{
Log.i(“服务器”,“服务器接收:”+incomingMsg);
setText(“服务器收到:+incomingMsg+”\n”);
append(“服务器发送:“+outgoingMsg+”\n”);
Log.i(“服务器”,“服务器已发送:”+outgoingMsg);
socket.close();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}否则{
Log.d(“服务器”,“无法与客户端通信!”);
}
}
}
这是我的客户:

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();
        }           
    }
}
公共类客户端扩展异步任务{
私人WifiManager-wifi;
私人语境;
私有字符串outMsg;
私有字符串inMsg;
公共客户端(上下文,WifiManager WifiManager){
this.context=上下文;
this.wifi=wifiManager;
}
@凌驾
受保护的套接字doInBackground(整数…参数){
试一试{
字符串gateway=intToIp(wifi.getDhcpInfo().gateway);
套接字=新套接字(网关,参数[0]);
BufferedReader in=新的BufferedReader(新的InputStreamReader(socket.getInputStream());
BufferedWriter out=新的BufferedWriter(新的OutputStreamWriter(socket.getOutputStream());
字符串ipAddress=intToIp(wifi.getConnectionInfo().getIpAddress());
outMsg=“,客户端”+iPAddress+“正在连接!”+System.getProperty(“line.separator”);
out.write(outMsg);
out.flush();
//接受服务器响应
inMsg=in.readLine()+System.getProperty(“line.separator”);
返回插座;
}捕获(未知后异常e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}
公共字符串intToIp(int addr){
返回((addr&0xFF)+“+
((地址>>=8)和0xFF)+“。”
((地址>>=8)和0xFF)+“。”
((addr>=8)和0xFF));
}
受保护的void onPostExecute(套接字){
if(套接字!=null){
Log.i(“客户端”,“客户端发送:”+outMsg);
Toast.makeText(上下文“\n客户端已发送“+outMsg+”\n”,Toast.LENGTH\u LONG.show();
Log.i(“客户”,“收到的客户:+inMsg”);
Toast.makeText(上下文,“客户端接收:”+inMsg+“\n”,Toast.LENGTH\u LONG.show();
}否则{
Log.d(“客户端”,“无法连接到服务器!”);
Toast.makeText(上下文“无法连接到服务器!”,Toast.LENGTH_LONG.show();
}           
}
}

如何利用服务器提供服务?客户端也应该是服务吗?

使用服务,但忘记异步任务。让您的服务启动通用线程()并设置套接字+侦听器。该服务甚至可以处理消息的发送(通过下面链接中介绍的众多选项之一)

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

还要注意,如果你想让应用程序继续接收来自其他客户端的消息,你需要确保服务被强制进入前台(请参阅,android.app.Notification)。然而,这并不是万无一失的,您的服务仍然可能被终止


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

不,只需将服务器保留在服务中就可以了OK,那么使用Servic呢