当前位置:首页 > CN2资讯 > 正文内容

android 服务器 模板 android web服务器

4天前CN2资讯


在android上如何编写一个小型web服务器?

这个是前几年之前接触到的一个项目的需求,需要是android手机建立一个无线热点,其他设备连接热点后,访问网站,都跳转到android手机上热点提供的网站,所以就需要android手机端实现一个简易的web服务器,服务器的资源文件都存储在sd卡,并且可以更新。

废话不多说,这边把项目早期做的可行性研究的demo整理了下,开源出来。

这个小型web服务器很大一部分参考AndroidWebServ工程(https:///joinAero/AndroidWebServ),在此多谢。

刚刚百度了下,已经有很多大牛也实现了类似的功能,用的方法也基本一致。这边在大概介绍下用到的具体技术

1:创建一个ServerSocket

2:使用HttpService创建一个Http服务,并为这个http创建需要的HTTP请求执行器(用来响应客户端发过来的get,download,upload等请求)

3:接收通过ServerSocket过来的Socket请求,并将Socket映射到HttpService上,这样HttpService就会返回对应的数据到客户端,客户端就能浏览网页了

核心代码在org.join.ws.serv.WebServer上,这边摘取部分片段

 

// 创建服务器套接字 serverSocket = new ServerSocket(port); // 设置端口重用 serverSocket.setReuseAddress(true); // 创建HTTP协议处理器 BasicHttpProcessor httpproc = new BasicHttpProcessor(); // 增加HTTP协议拦截器 httpproc.addInterceptor(new ResponseDate()); httpproc.addInterceptor(new ResponseServer()); httpproc.addInterceptor(new ResponseContent()); httpproc.addInterceptor(new ResponseConnControl()); // 创建HTTP服务 HttpService httpService = new HttpService(httpproc, new DefaultConnectionReuseStrategy(), new DefaultHttpResponseFactory()); // 创建HTTP参数 HttpParams params = new BasicHttpParams(); params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000) .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false) .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "WebServer/1.1"); // 设置HTTP参数 httpService.setParams(params); // 创建HTTP请求执行器注册表 HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry(); // 增加HTTP请求执行器 reqistry.register(UrlPattern.DOWNLOAD, new HttpDownHandler(webRoot)); reqistry.register(UrlPattern.DELETE, new HttpDelHandler(webRoot)); reqistry.register(UrlPattern.UPLOAD, new HttpUpHandler(webRoot)); reqistry.register(UrlPattern.PROGRESS, new HttpProgressHandler()); reqistry.register(UrlPattern.BROWSE, new HttpFBHandler(webRoot)); // 设置HTTP请求执行器 httpService.setHandlerResolver(reqistry); // 回调通知服务开始 if (mListener != null) { mListener.onStarted(); } /* 循环接收各客户端 */ isLoop = true; while (isLoop && !Thread.interrupted()) { // 接收客户端套接字 Socket socket = serverSocket.accept(); // 绑定至服务器端HTTP连接 DefaultHttpServerConnection conn = new DefaultHttpServerConnection(); conn.bind(socket, params); // 派送至WorkerThread处理请求 Thread t = new WorkerThread(httpService, conn, mListener); t.setDaemon(true); // 设为守护线程 pool.execute(t); // 执行 }

项目中还用到 一个比较重要的库,Jangod,这个库很强大,可以用来从文件或者从代码中加载html,并支持css,有兴趣的同学可以 继续研究下去。

 

另外还有一个问题,怎么样把客户端所有的http请求都引到我们的ServerSocket?这边就需要用到nat表了,前提是你手机root了

1:将所有对80端口的http请求都强制转换到我们的ServerSocket,命令如下

 

String cmd = "iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p tcp --dport 80 -j DNAT --to-destination " +CommonUtil.getLocalIpAddress()+":" + Config.PORT;//192.168.43.1:7766";

2:将 所有对53端口的dns请求都强制装换到我们的dns请求端口,并实现dns的响应 

String cmd53 = "iptables -t nat -A PREROUTING -d 0.0.0.0/0 -p udp --dport 53 -j DNAT --to-destination " +CommonUtil.getLocalIpAddress()+":" + Config.PORT_DNS;//192.168.43.1:7766";

 

package org.join.ws.serv; import java.io.IOException; import .DatagramPacket; import .DatagramSocket; import .ServerSocket; import .Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.http.impl.DefaultConnectionReuseStrategy; import org.apache.http.impl.DefaultHttpResponseFactory; import org.apache.http.impl.DefaultHttpServerConnection; import org.apache.http.params.BasicHttpParams; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.params.HttpParams; import org.apache.http.protocol.BasicHttpProcessor; import org.apache.http.protocol.HttpRequestHandlerRegistry; import org.apache.http.protocol.HttpService; import org.apache.http.protocol.ResponseConnControl; import org.apache.http.protocol.ResponseContent; import org.apache.http.protocol.ResponseDate; import org.apache.http.protocol.ResponseServer; import org.join.ws.Constants.Config; import org.join.ws.serv.req.HttpDelHandler; import org.join.ws.serv.req.HttpDownHandler; import org.join.ws.serv.req.HttpFBHandler; import org.join.ws.serv.req.HttpProgressHandler; import org.join.ws.serv.req.HttpUpHandler; import org.join.ws.util.CommonUtil; /** * @brief DnsWeb服务类 * @author talkercenter */ public class DnsServer extends Thread { static final String TAG = "DnsServer"; static final boolean DEBUG = false || Config.DEV_MODE; byte[] requestBuffer = new byte[256]; byte[] responseBuffer = new byte[256]; byte[] ipBuffer = { (byte) 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x7c, 0x00, 0x04, (byte)0xc0, (byte)0xa8, 0x2b, 0x01 }; public static final int ERR_UNEXPECT = 0x0101; public static final int ERR_PORT_IN_USE = 0x0102; public static final int ERR_TEMP_NOT_FOUND = 0x0103; private int port; //private String webRoot; private DatagramSocket serverSocket; /* package */static boolean isLoop; private OnWebServListener mListener; //private ExecutorService pool; // 线程池 public DnsServer(int port, final String webRoot) { super(); this.port = port; //this.webRoot = webRoot; isLoop = false; //pool = Executors.newCachedThreadPool(); } @Override public void run() { try { // Decide if port is in use. if (CommonUtil.getSingleton().isLocalPortInUse(port)) { if (mListener != null) { mListener.onError(ERR_PORT_IN_USE); } return; } // 创建服务器套接字 serverSocket = new DatagramSocket(port); DatagramPacket requestPacket = new DatagramPacket(requestBuffer,requestBuffer.length); /* 循环接收各客户端 */ isLoop = true; while (isLoop && !Thread.interrupted()) { serverSocket.receive(requestPacket); int requestLength = requestPacket.getLength(); System.arraycopy(requestBuffer, 0, responseBuffer, 0, requestLength); System.arraycopy(ipBuffer, 0, responseBuffer, requestLength, ipBuffer.length); // 标志位 responseBuffer[2] = (byte) 0x81; responseBuffer[3] = (byte) 0x80; // 响应数 responseBuffer[6] = (byte) 0x00; responseBuffer[7] = (byte) 0x01; DatagramPacket response = new DatagramPacket(responseBuffer, requestLength + ipBuffer.length, requestPacket.getAddress(), requestPacket.getPort()); serverSocket.send(response); } } catch (IOException e) { if (isLoop) { // 以排除close造成的异常 // 回调通知服务出错 if (mListener != null) { mListener.onError(ERR_UNEXPECT); } if (DEBUG) e.printStackTrace(); isLoop = false; } } finally { try { if (serverSocket != null) { serverSocket.close(); } // 回调通知服务结束 if (mListener != null) { mListener.onStopped(); } } catch (Exception e) { } } } public void close() { isLoop = false; try { if (serverSocket != null) { serverSocket.close(); } } catch (Exception e) { } } public interface OnWebServListener { void onStarted(); void onStopped(); void onError(int code); } public void setOnWebServListener(OnWebServListener mListener) { this.mListener = mListener; } }

 

结束,完整代码请访问

https:///bobohuang1985/android-utils-api


    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/20799.html

    分享给朋友:

    “android 服务器 模板 android web服务器” 的相关文章

    Digital-VM优惠活动揭秘:享受五折折扣和稳定续费

    Digital-VM优惠概述 Digital-VM简介 Digital-VM是一家专注于提供基于KVM架构的VPS主机服务商,凭借其强大的服务器性能和丰富的网络资源,已经逐渐在市场中站稳了脚跟。如果你在寻找高可靠性、灵活配置的VPS主机,Digital-VM绝对值得一试。它在全球多个地区建立了数据中...

    详细指南:如何进行Linux扩容以解决存储不足问题

    什么是Linux扩容? 在使用Linux操作系统时,随着数据的增加,我们常常面临磁盘空间不足的问题。Linux扩容就是通过添加新的磁盘、扩展现有磁盘容量或利用逻辑卷管理(LVM)等方式,来增加系统的存储空间。扩容可以帮助我更好地管理数据,提高服务器的运行效率。 我记得第一次接触扩容时,面对不断增加的...

    BuyVM色情网站托管服务解析 - 提升成人内容运营安全与效率

    什么是BuyVM色情服务 当我提到BuyVM的时候,可能很多人对这个名字还不太熟悉。简单来说,BuyVM是一家提供虚拟专用服务器(VPS)和网站托管服务的公司,专注于各种类型的内容,包括成人色情内容。它的历史可以追溯到多个年份前,BuyVM在业内逐渐赢得了声誉,成为不少成人网站的首选托管平台。以其可...

    AT&T VPS详解:稳定性与灵活性的完美选择

    在这篇文章中,我想和大家聊聊AT&T VPS,尤其是在更广泛的虚拟私有服务器市场中,AT&T VPS代表了什么。AT&T是一家美国知名的电信运营商,其提供的VPS服务在一定程度上依赖于它的网络基础设施。这种结合了高质量网络与虚拟服务器技术的服务,吸引了大量需要高稳定性和可扩展...

    OVH 黑五促销活动详解:服务器折扣与购买指南

    OVH 黑五活动概述 在每年感恩节后的第一天,黑色星期五(Black Friday)成了一年中最大的购物盛事之一。它起源于美国,最初是零售商为了清理库存而设立的特价销售日。随着时间的推移,黑五的影响力逐渐扩展至全球,成为各种行业都参与的一次购物狂欢。对于消费者而言,这不仅是一次购物机会,更是寻找到心...

    P100 GPU价格分析及购买指南 - 如何选择性价比最高的GPU

    在如今的计算技术中,P100 GPU扮演了一个至关重要的角色。尤其是对于那些需要进行大量并行计算的任务,比如深度学习、科学模拟和数据分析,P100 GPU是一款极具吸引力的选项。作为NVIDIA推出的高性能计算单元,P100 GPU不仅具备强大的计算能力,还拥有一系列先进的技术规格,使其在行业中脱颖...