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