Android版Web服务器实现(二)使用服务来监听HTTP请求
来源:互联网 发布:阿里云邮箱故障 编辑:程序博客网 时间:2024/06/05 02:20
《Android版Web服务器实现(一)HTTP协议请求头解析》一文中说到了HTTP协议请求头的解析,那么我们要如何得到这个HTTP请求头呢?我们需要监听端口。监听是一直要运行着的,在Android中比较好的方式就是使用服务。下面是实现的代码。
WebServer.java
package com.sparkle.webservice;import java.io.IOException;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.ServerSocket;import android.app.Service;import android.content.Context;import android.content.Intent;import android.net.wifi.WifiManager;import android.os.IBinder;import android.util.Log;import com.sparkle.kits.IP;public class WebServer extends Service implements Runnable {private static boolean _isRunning = false;private static Thread _serverThread = null;private ServerSocket _listenSocket = null;private MyLog _myLog = new MyLog(getClass().getName());private static int _port = Defaults.getPort();private TcpListener _tcpListener = null;private static final int WAKE_INTERVAL_MS = 1000;public WebServer() {try {Init();} catch (IOException e) {e.printStackTrace();}}private void Init() throws IOException {_listenSocket = new ServerSocket();_listenSocket.setReuseAddress(true);_listenSocket.bind(new InetSocketAddress(_port));}public static void Start(Context context) {if (!_isRunning) {_isRunning = true;Intent intent = new Intent(context, WebServer.class);context.startService(intent);}}public static void Stop(Context context) {if (_isRunning) {_isRunning = false;Intent intent = new Intent(context, WebServer.class);context.stopService(intent);}}public static boolean isRunning() {return _isRunning;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int attempts = 10;// The previous server thread may still be cleaning up,// wait for it to finish.while (_serverThread != null) {_myLog.l(Log.WARN, "Won't start, server thread exists");if (attempts <= 0) {_myLog.l(Log.ERROR, "Server thread already exists");return super.onStartCommand(intent, flags, startId);}try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}attempts--;}_myLog.l(Log.DEBUG, "Creating server thread");_serverThread = new Thread(this);_serverThread.start();return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {if (_tcpListener != null) {_tcpListener.quit();}_myLog.l(Log.INFO, "onDestroy() Stopping server");if (_serverThread == null) {_myLog.l(Log.WARN, "Stopping with null serverThread");return;}_serverThread.interrupt();try {_serverThread.join(10000); // wait 10 second for server thread to// finish} catch (InterruptedException e) {}if (_serverThread.isAlive()) {_myLog.l(Log.WARN, "Server thread failed to exit");} else {_myLog.d("serverThread joined ok");_serverThread = null;}try {if (_listenSocket != null) {_listenSocket.close();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}UiUpdater.updateClients();_myLog.d("WebService.onDestroy() finished");}@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void run() {// Server thread run.while (_isRunning) {UiUpdater.updateClients();if (_tcpListener == null) {_tcpListener = new TcpListener(_listenSocket, this);_tcpListener.start();}try {Thread.sleep(WAKE_INTERVAL_MS);} catch (InterruptedException e) {_myLog.l(Log.DEBUG, "Thread interrupted");}}}public static InetAddress getWifiIp(Context context) {if (context == null) {throw new NullPointerException("Global context is null");}WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);if (!wifiManager.isWifiEnabled()) {return null;}int ipAsInt = wifiManager.getConnectionInfo().getIpAddress();if (ipAsInt == 0) {return null;} else {return IP.intToInet(ipAsInt);}}public static int getPort() {return _port;}}注:
1、WebServer继承自Service,内部套了一个服务的线程,所以又实现了Runnable接口。
2、重载onStartCommand方法,在该方法中启动服务线程_serverThread。在启动时,进行探测,以确保前一次启动的_serverThread已经关闭。
3、重载onDestroy方法,在该方法中关闭服务线程。
4、在run方法中,启用监听_tcpListener。TcpListener是一个封装的类,具体参看后面的代码。
5、附上getWifiIp和getPort方法,以方便调用。
6、UiUpdater是一个界面更新器,具体的请参看后文的代码。
7、服务需要在AndroidManifest.xml中注册,注册部分代码如下。
AndroidManifest.xml部分代码
<application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.sparkle.webservice.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.sparkle.webservice.WebServer" /> </application>
TcpListener.java
package com.sparkle.webservice;import java.net.ServerSocket;import java.net.Socket;import android.util.Log;public class TcpListener extends Thread {private ServerSocket _listenSocket = null;private MyLog _myLog = new MyLog(getClass().getName());public TcpListener(ServerSocket listenSocket, WebServer webServer) {this._listenSocket = listenSocket;}public void quit() {try {_listenSocket.close(); // if the TcpListener thread is blocked on// accept,// closing the socket will raise an// exception} catch (Exception e) {_myLog.l(Log.DEBUG, "Exception closing TcpListener listenSocket");}}public void run() {try {while (true) {Socket clientSocket = _listenSocket.accept();_myLog.l(Log.INFO, "New connection, spawned thread");SessionThread newSession = new SessionThread(clientSocket);newSession.start();}} catch (Exception e) {_myLog.l(Log.DEBUG, "Exception in TcpListener");}}}注:
1、在run中使用accept的阻塞方法来监听。
2、在收到请求后,放到SessionThread中去处理,该部分代码请参看后文。
3、MyLog是自定义的一个日志类。
MyLog.java
package com.sparkle.webservice;import android.util.Log;public class MyLog {protected String tag;public MyLog(String tag) {this.tag = tag;}public void l(int level, String str, boolean sysOnly) {synchronized (MyLog.class) {str = str.trim();Log.println(level, tag, str);}}public void l(int level, String str) {l(level, str, false);}public void e(String s) {l(Log.ERROR, s, false);}public void w(String s) {l(Log.WARN, s, false);}public void i(String s) {l(Log.INFO, s, false);}public void d(String s) {l(Log.DEBUG, s, false);}}
注:日志输出时使用synchronized来确保日志的输出。
监听到了HTTP的请求后,需要对其进行处理以作出响应,具体请看下一篇。
转载请注明出处:Android版Web服务器实现(二)使用服务来监听HTTP请求
源码下载
0 0
- Android版Web服务器实现(二)使用服务来监听HTTP请求
- Android版Web服务器实现(一)HTTP协议请求头解析
- Android 下使用 JSON 实现 HTTP 请求(自整合而来)
- socket实现简单web服务器,可查看http请求信息
- Android版Web服务器实现(三)HTTP响应
- Web服务器和http请求
- 使用android-async-http来封装Android网络请求框架
- 使用内部的方法来实现HTTP请求
- Android 下使用 JSON 实现 HTTP 请求
- Android 下使用 JSON 实现 HTTP 请求
- Android 下使用 JSON 实现 HTTP 请求
- Android 下使用 JSON 实现 HTTP 请求
- Android 下使用 JSON 实现 HTTP 请求
- Android下使用JSON 实现HTTP请求
- Android中使用httpClient实现HTTP请求
- 使用Netty构建APP后台服务器实现http请求
- 各种HTTP状态汇总 (web服务器请求服务报错提示)
- android 实现http请求
- 好帖子收集总结
- POJ2661 Factstone Benchmark
- 转载一个C#应用程序打包的详细教程,超详细!
- UNDO 100%
- git rebase 小计
- Android版Web服务器实现(二)使用服务来监听HTTP请求
- 关于 jquery easy ui onLoad 获取参数
- Perl、PHP、Python、Java和Rub之间的异同比较
- 自己动手开发音乐播放器《六》播放方式的实现
- 过滤器
- ant的命令
- 硬盘结构,主引导记录MBR,硬盘分区表DPT,主分区、扩展分区和逻辑分区
- UFLDL 教程学习笔记(四)主成分分析
- win7系统用sqlyog连接ubuntu虚拟机上的mysql数据库