如何让安卓手机访问内网服务器
先说明服务器是什么,如果是WEB服务器或是FTP服务器的,只需在内网上拉一根网线接入无线路由器,手机通过WIFI访问内网服务器。
如果是手机通过外网访问内网的服务器的话,则要有固定IP,通过固定IP所设置比如交换机NAT映射到内网服务器的内网IP。手机只需在浏览器上输入你的外网固定Ip就可以访问内网服务器了
希望采纳!
Android的网络编程分为2种:基于http协议的,和基于socket的。Socket一般应用于社交聊天的应用中,这里关联的比较少就不讲了,我们来说说基于HTTP协议的编程。
基本原理 : 它的工作原理特别的简单,就是客户端向服务器发出一条HTTP 请求,服务器收到请求之后会返回一些数据给客户端,然后客户端再对这些数据进行解析和处理就可以了。
HTTP请求:HttpURLConnection 和 HttpClient
服务器端返回客户端的内容:
1)以HTML代码的形式返回。
2)以XML字符串的形式返回。返回的数据需要通过XML解析(SAX、DOM,Pull,等)器进行解析。
3)以json对象的方式返回。
commons-netjar里面有ftp相关的接口,这个是我自己封装的一个类
import javaioFileInputStream;
import javaioIOException;
import javanetSocket;
import javautilArrayList;
import javautilList;
import orgapachecommonsnetftpFTP;
import orgapachecommonsnetftpFTPClient;
import orgapachecommonsnetftpFTPReply;
import androidappActivity;
import androidcontentContext;
import androidcontentSharedPreferences;
public class FTPUtils {
/
通过ftp上传文件
@param fileNamePath
要上传的文件路径 , 以'结'尾
@param fileName
要上传的文件名
@return 如果成功返回"" , 否则返回错误结果
/
public static String ftpUpload(String sdcardFullFileName, String fileName, String ftpPath) {
FTPClient ftpClient = new FTPClient();
FileInputStream fis = null;
String returnMessage = "";
try {
ftpClientconnect(ConnectConfigftpIP, ConnectConfigftpPort);
boolean loginResult = ftpClientlogin(ConnectConfigftpUserName, ConnectConfigftpPassWord);
int returnCode = ftpClientgetReplyCode();
if (loginResult && FTPReplyisPositiveCompletion(returnCode)) {// 如果登录成功
String[] splits = ftpPathsplit("/");
String temps = splits[0];
ftpClientmakeDirectory(temps);
for(int i=1;i<splitslength;i++){
temps += "/" + splits[i];
ftpClientmakeDirectory(temps);
}
// ftpClientmakeDirectory(ftpPath);
// 设置上传目录
ftpClientchangeWorkingDirectory(ftpPath);
ftpClientsetBufferSize(1024);
ftpClientsetControlEncoding("UTF-8");
ftpClientsetFileType(FTPBINARY_FILE_TYPE);
ftpCliententerLocalPassiveMode();
fis = new FileInputStream(sdcardFullFileName);
// boolean result = ftpClient(fileName, fis);
boolean result = ftpClientstoreFile(fileName, fis);
if(result){
returnMessage = ""; // 上传成功
}else{
returnMessage = "上传失败";
}
} else {// 如果登录失败
returnMessage = "登录FTP时失败,FTP用户名或者密码错误!";
}
} catch (IOException e) {
// ftp发送出现异常
eprintStackTrace();
returnMessage = "FTP客户端出错!" + e;
} finally {
try {
ftpClientdisconnect();
} catch (IOException e) {
eprintStackTrace();
}
}
return returnMessage;
}
}
不能与数据库连接的
Android客户端不能直接与服务器数据库连接。数据库是需要非常大的内存,安装之后有好几G,连接数据库要有一个像SQLServer里的webservice,这样的一个桥梁来间接访问。就是在服务器运行一个服务端程序,该服务端程序通过接收来自android客户端的指令,对数据库进行操作。
客户端的http请求可以通过 HttpClient类实现,在anddroid 40之后,客户端的网络请求已经不被允许在主线程中运行,所以还需注意另开启一个子线程进行网络请求。
扩展资料:
Android安全权限机制:
Android默认设置下,所有应用都没有权限对其他应用、系统或用户进行较大影响的操作。这其中包括读写用户隐私数据(联系人或电子邮件),读写其他应用文件,访问网络或阻止设备待机等。安装应用时,在检查程序签名提及的权限,且经过用户确认后,软件包安装器会给予应用权限。
下载一款Android应用通常会要求如下的权限:拨打电话、发送短信或彩信、修改/删除SD卡上的内容、读取联系人的信息、读取日程信的息,写入日程数据、读取电话状态或识别码、精确的(基于GPS)地理位置、模糊的(基于网络获取)地理位置、创建蓝牙连接、
还有对互联网的完全访问、查看网络状态,查看WiFi状态、避免手机待机、修改系统全局设置、读取同步设定、开机自启动、重启其他应用、终止运行中的应用、设定偏好应用、震动控制、拍摄等。
——Android
方法如下:
在Activity中调用 JsonUtil工具类 只需要
调用findAll方法即可,如:
JsonUtilfindAll(strUrl); // strUrl: 连接地址
若需要传值如s:strUrl = http:127001:8080/xxxxid=1&name=shsjhs;
public class JsonUtil {
public static String json;
public static String findAll(String strUrl) throws Exception {
// 创建请求HttpClient客户端
Systemoutprintln("连接上服务器");
HttpClient httpClient = new DefaultHttpClient();
// 创建请求的url
// 创建请求的对象
HttpGet get = new HttpGet(new URI(strUrl));
// 发送get请求
HttpResponse httpResponse = httpClientexecute(get);
// 如果服务成功返回响应
if (httpResponsegetStatusLine()getStatusCode() == 200) {
HttpEntity entity = httpResponsegetEntity();
if (entity != null) {
// 获取服务器响应的json字符串
json = EntityUtilstoString(entity, "UTF-8");
Systemoutprintln(json); //输出返回的字符串信息
}
} else {
Systemoutprintln("连接超时");
}
return json;
}
}
这种功能实际上就是数据同步,同时要考虑手机本身、电量、网络流量等等限制因素,所以通常在移动端上有一下两个解决方案:
1一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器,称Polling(轮询);
2还有一种是移动端和服务器建立长连接,使用XMPP长连接,称Push(推送)。
从耗费的电量、流量和数据延迟性各方面来说,Push有明显的优势。但是使用Push的缺点是:
对于客户端:实现和维护相对成本高,在移动无线网络下维护长连接,相对有一些技术上的开发难度。
对于服务器:如何实现多核并发,cpu作业调度,数量庞大的长连接并发维护等技术,仍存在开发难点。
在讲述Push方案的原理前,先了解一下移动无线网络的特点。
移动无线网络的特点:
因为 IP v4 的 IP 量有限,运营商分配给手机终端的 IP 是运营商内网的 IP,手机要连接 Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网 IP、端口到内网 IP、端口的对应关系,以确保内网的手机可以跟 Internet 的服务器通讯
GGSN(Gateway GPRS
Support Node 网关GPRS支持结点)模块就实现了NAT功能。
因为大部分移动无线网络运营商都是为了减少网关的NAT映射表的负荷,所以如果发现链路中有一段时间没有数据通讯时,会删除其对应表,造成链路中断。
Push在Android平台上长连接的实现:
既然自己知道自己移动端要和Internet进行通信,必须通过运营商的网关,所以,为了不让NAT映射表失效,咋们需要定时向Internet发送数据,因为只是为了不然NAT映射表失效,所以只需发送长度为0的数据即可。
这时候就要用到定时器,在android系统上,定时器通常有一下两种:
1javautilTimer
2androidappAlarmManager
分析:
Timer:可以按照计划或者时间周期来执行相关的任务。但是Timer需要用WakeLock来让CPU保持唤醒状态,才能保证任务的执行,这样子会消耗大量流量;当CPU处于休眠的时候,就不能唤醒执行任务,所以应用于移动端明显是不合适。
AlarmManager:AlarmManager类是属于android系统封装好来管理RTC模块的管理类。这里就涉及到RTC模块,要更好地了解两者的区别,就要明白两者真正的区别。
RTC(Real- Time Clock)实时闹钟在一个嵌入式系统中,通常采用RTC
来提供可靠的系统时间,包括时分秒和年月日等;而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电),它的外围也不需要太多的辅助电路,典型的就是只需要一个高精度的32768KHz
晶体和电阻电容等。(如果对这方面感兴趣,可以自己查阅相关资料,这里就说个大概)
好了,回来正题。所以,AlarmManager又称全局定时闹钟。这意味着,当自己用使用AlarmManager来定时执行任务,CPU可以正常地休眠,只有在执行任务是,才唤醒CPU,这个过程是很短时间的。
下面简单来说明其使用:
1类似于Timer功能:
//获得闹钟管理器
AlarmManager
am = (AlarmManager)getSystemService(ALARM_SERVICE);
//设置任务执行计划
amsetRepeating(AlarmManagerELAPSED_REALTIME, firstTime, 51000,
sender);//从firstTime才开始执行,每隔5秒再执行
2实现全局定时功能:
//获得闹钟管理器
AlarmManager
am = (AlarmManager)getSystemService(ALARM_SERVICE);
//设置任务执行计划
amsetRepeating(AlarmManagerELAPSED_REALTIME_WAKEUP, firstTime,
51000, sender);//从firstTime才开始执行,每隔5秒再执行
总结:在android客户端使用Push推送时,应该使用AlarmManager来实现心跳功能,使其真正实现长连接。
package comtest;
import javaioBufferedReader;
import javaioInputStreamReader;
import javaioOutputStream;
import javanetHttpURLConnection;
import javanetURL;
import javanetURLEncoder;
import javautilHashMap;
import javautilMap;
import orgjsonJSONObject;
import androidappActivity;
import androidcontentIntent;
import androidosBundle;
import androidosHandler;
import androidosLooper;
public class TestPost extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
superonCreate(savedInstanceState);
setContentView(Rlayoutloading);
new Handler()postDelayed(new Runnable() {
@Override
public void run() {
final Map<String, String> params0 = new HashMap<String, String>();
params0put("username", username);
params0put("password", password);
final String url0 = "http://192168011:80/xxxxphp";
Runnable downloadRun = new Runnable() {
@Override
public void run() {
Looperprepare();
try {
String result0 = sendPostRequest(
params0, url0);
JSONObject jsonObject = new JSONObject(result0);
String status = jsonObjectgetString("status");
String message = jsonObjectgetString("message");
if (statusequals("success")) {
//成功干啥
} else {
//失败干啥
}
} catch (Exception e) {
//出现异常干啥
}
}
};
new Thread(downloadRun)start();
}
}, 200);
}
//post请求方法
public String sendPostRequest(Map<String, String> params, String actionurl)
throws Exception {
String URl = actionurl;
StringBuilder sb = new StringBuilder();
if (params != null && !paramsisEmpty()) {
for (MapEntry<String, String> entry : paramsentrySet()) {
sbappend(entrygetKey())append('=')
append(URLEncoderencode(entrygetValue(), "UTF-8"))
append('&');
}
sbdeleteCharAt(sblength() - 1);
}
byte[] entitydata = sbtoString()getBytes();// 得到实体的二进制数据
URL url = new URL(URl);
HttpURLConnection conn = (HttpURLConnection) urlopenConnection();
connsetDoInput(true);
connsetRequestMethod("POST");
connsetConnectTimeout(10000);
connsetDoOutput(true);// 如果通过post提交数据,必须设置允许对外输出数据
connsetUseCaches(false);// 是否缓存
connsetRequestProperty("Content-Type","application/x-www-form-urlencoded");
connsetRequestProperty("Content-Length",StringvalueOf(entitydatalength));
OutputStream outStream = conngetOutputStream();
outStreamwrite(entitydata);
outStreamflush();
outStreamclose();
BufferedReader bufferRead = null;
if(conngetResponseCode() == 200){
bufferRead = new BufferedReader(new InputStreamReader(conngetInputStream()));
}
String result = "";
String readLine = null;
while ((readLine = bufferReadreadLine()) != null) {
result += readLine;
}
bufferReadclose();
conndisconnect();
return result;
}
}
我用的是这种方法
android 中网络请求,超过5秒没有响应就会出现超时的,你应该检测这个超时啊,如果超时了提示用户请求超时,是否重试等等,而不是一直让对话框在哪缓冲,这只是处理这问题的我的思路,希望可以帮到你,代码自己敲吧,刚帮别人敲了几段敲不动了,还要继续工作呢,祝你顺利。
0条评论