上个项目收尾的时候,突然发生的一个问题:联通或者移动的wap接入点无法登陆应用,会一直显示登陆,不会有请求返回,直到请求超时为止。当时很差异为什么会发生这种情况,然后加了一个请求代理就OK了,现在终于有时间总结下这是为什么?这个疑问一直存在我的心中,今天终于有时间解开我的疑问了。
首先你必须了解什么是wap和net。
CMNET、CMWAP都是手机上网使用的接入点的名称。
联通等运营商也有类似区别的服务。
这里以移动的CMNET和CMWAP为例,他们的区别是:
通过CMNET可以获得完全的Internet访问权,可以访问pop和imap等众多互联网服务;
通过CMWAP只能访问网页,无法访问pop和imap等众多互联网服务。
CMWAP和CMNET费用和设置:
CMWAP和CMNET是移动的两种接入点,分别包含在各种套餐中,CMWAP是比较便宜的,
CMNET较贵,但是因为是标准的互联网协议,他的特点是快。
所以在手机设置中要看好自己这种的接入点是什么,
如果你仅仅包了cmwap但是使用了cmnet,会产生额外并且巨大的费用。
(1) 为什么会有两个接入点?
在国际上,通常只有一种GPRS接入方式,为什么在中国会有CMWAP和CMNET两兄弟呢?(彩信之所以单独配置接入点是因为彩信服务需要连接专用的服务器,在这里不作探讨。)
其实,CMWAP 和 CMNET 只是中国移动人为划分的两个GPRS接入方式。前者是为手机WAP上网而设立的,后者则主要是为PC、笔记本电脑、PDA等利用GPRS上网服务。它们在实现方式上并没有任何差别,但因为定位不同,所以和CMNET相比,CMWAP便有了部分限制,资费上也存在差别。
(2) 什么是WAP?
WAP只是一种GPRS应用模式,它与GRPS的接入方式是无关的。WAP应用采用的实现方式是“终端+WAP网关+WAP服务器”的模式,不同于一般Internet的“终端+服务器”的工作模式。主要的目的是通过WAP网关完成WAP-WEB的协议转换以达到节省网络流量和兼容现有WEB应用的目的。
WAP网关从技术的角度讲,只是一个提供代理服务的主机,它不一定由网络运营商提供。但据我所知,中国移动GPRS网络目前只有唯一的一个WAP网关:10.0.0.172,有中国移动提供,用于WAP浏览(HTTP)服务。有一点需要注意,WAP网关和一般意义上的局域网网关是有差别的,标准的WAP网关仅仅实现了HTTP代理的功能,并未完成路由、NAT等局域网网关的功能。这就决定了它在应用上所受到的限制。
(3) 中国移动对CMWAP的限制
为了从应用中区别两者的定位,中国移动对CMWAP作了一定的限制,主要表现在CMWAP接入时只能访问GPRS网络内的IP(10.*.*.*),而无法通过路由访问Internet。(少数地区的移动网络可能不存在这一限制。)我们用CMWAP浏览Internet上的网页就是通过WAP网关协议或它提供的HTTP代理服务实现的。
说到这里,就让我自然而然的联想到公司的网络,相信不少工作的朋友都有类似的体会。公司的网络在网关上不提供路由和NAT,仅仅提供一个可以访问外网的HTTP代理。这样,我们就无法直接使用QQ、MSN等非HTTP协议的应用软件了(好在它们还提供的有HTTP代理的连接方式)。CMWAP也正是如此。
(4) 适用范围
适用范围才是大家最关心的问题。CMNET拥有完全的Internet访问权,这里就不多说了,主要让我们来看看CMWAP。因为有了上面提到的限制,CMWAP的适用范围就要看WAP网关所提供的支持了。目前,中国移动的WAP网关对外只提供HTTP代理协议(80和8080端口)和WAP网关协议(9201端口)。
因此,只有满足以下两个条件的应用才能在中国移动的CMWAP接入方式下正常工作:
1. 应用程序的网络请求基于HTTP协议。
2. 应用程序支持HTTP代理协议或WAP网关协议。
如何辨别一个应用程序的网络请求是否基于HTTP协议?
这个问题还真不好回答,要完全做到这一点需要通过拦截应用程序的通信数据包进行分析。这里提供几个简单的方法给广大菜鸟朋友:从表现上看,如果它的网络请求是网址(URL)的形式,那么通常是基于HTTP协议的,如Web浏览器;如果它连接的服务器端口是80,那么它可能是基于HTTP协议的。如果确实无法准确判断,那么请直接看下一个条件。(满足第二个条件的应用一定是基于HTTP协议的)
如何区别一个应用程序支持HTTP代理协议还是WAP网关协议呢?
首先看它的设置中有没有代理服务器的选项(通常在S60上未特别说明的代理都是特指HTTP代理),如果有则表示它支持HTTP代理协议。如果没有,则需要按照以下步骤测试:
在GPRS接入点设置的高级设置里去掉代理服务器的设置项:Server Address 和 Server Port,如果应用程序可以正常工作,那么它是基于WAP网关协议,如Java程序、S60内置的浏览器。如果在此状态下不能正常工作,而恢复GPRS接入点高级设置中的代理服务器设置后能够正常工作,则应用程序支持HTTP代理协议(代理设置从系统中读取)。如果仍不能正常工作,那么这个应用程序一般来说是不支持 HTTP代理协议或WAP网关协议的。
继续解答:
有煤油问,wap可不可以看在线视频,回答可以,只要你有20无限wap包月你下载uc7。1在下个ucM8专用播放器就可以看在线视频了。流畅度一般但是比诺基亚要好的多。很方便。
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
/**
* 下载器
*/
public class DownloadUtil {
private static final String TAG = "Downloader";
/**
* @return InputStream 下载
*/
public static HttpURLConnection download(String url) {
HttpURLConnection conn = null;
try {
String proxyHost = android.net.Proxy.getDefaultHost();
if (proxyHost != null) {//如果是wap方式,要加网关
java.net.Proxy p = new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress(
android.net.Proxy.getDefaultHost(), android.net.Proxy.getDefaultPort()));
conn = (HttpURLConnection) new URL(url).openConnection(p);
} else {
conn = (HttpURLConnection) new URL(url).openConnection();
}
// conn.setReadTimeout(5000);
conn.setConnectTimeout(10000);
conn.setRequestMethod("GET");
conn.setRequestProperty(
"Accept",
"image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*");
conn.setRequestProperty("Accept-Language", "zh-CN");
conn.setRequestProperty("Referer", url);
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty(
"User-Agent",
"Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
return conn;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
我们最开始的实现方式就使用HttpUrlConnection,但是因为这个无法在wap网络下登陆,最后没办法,切换成HttpClient,并且加了代理就可以了。刚刚发现上面的代码,就是对HttpUrlConnection加了代理,上次就是没看到这份代码,要不也不用改动那么大了。
仅以此记录,这个真是挺重要的。
然后继续百度了一下,发现几篇真心不错的文章,分享给大家。
一、原文链接:http://www.linuxidc.com/Linux/2012-08/67980.htm
无论是移动、联通还是电信,都至少提供了两种类型的的APN:WAP方式和NET方式。其中NET方式跟WIFI方式一样,无需任何设置,可自由访问所有类型网站,而WAP方式,需要手机先设置代理服务器和端口号等信息,并且只能访问HTTP协议类型的网站。
1) 移动的WAP名称是CMWAP,NET名称是CMNET;
2) 联通的WAP名称是UNIWAP,NET名称是UNINET;联通3G的WAP名称是3GWAP,NET名称是3GNET;
3) 电信的WAP名称是CTWAP,NET名称是CTNET;
其中,移动和联通的WAP代理服务器都是10.0.0.172,端口号是80;而电信的WAP代理服务器是10.0.0.200,端口号是80。
Android系统中,对于APN网络的API是隐藏的,因此获取手机的APN设置,需要通过ContentProvider来进行数据库查询,查询的URI地址是:
取得全部的APN列表:content://telephony/carriers;
取得当前设置的APN:content://telephony/carriers/preferapn;
取得current=1的APN:content://telephony/carriers/current;
二、这篇讲的也很细致,很多注意事项,太棒了。
http://www.jizhuomi.com/android/example/32.html
三、android判断2g|3g网络
http://hi.baidu.com/neverever888/item/0c37d436553ddc1d9cc65ee0
2013-5-9号补充:
Android应用程序访问互联网资源时,在Wifi的情况下处理网络连接按照上文所讲述的方法步骤即可顺利实现;但如果当前Android设备的联网方式是通过移动运营商的网络服务为中转,间接访问的互联网资源时,则就涉及到在创建HTTP链接之前需要设置Proxy,即可尽量避免网络中断访问的情况,顺利访问互联网。
Proxy中文即代理。已经插入手机卡的Android设备,点击"设置"→"无线和网络"→"移动网络设置"→"接入点名称",任意点击一接入点,此时显示的内容即为当前运营商为使Android设备通过运营商网络顺利接入互联网而需要设置的代理信息。
通常,中国移动的接入点为CMWAP,代理IP是10.0.0.172,端口为80。
由于不同运营商其代理设置的不同,为保证代码的一致性及有效性,开发过程中需要封装出能够自适应各种不同Proxy环境并且能够顺利访问互联网的联网代码。
封装后的方法为openUrl(),代码如下:
01 | public static HttpURLConnection openUrl(Context context, String urlStr) { |
03 |
HttpURLConnection httpConn = null ; |
05 |
urlURL = new URL(urlStr); |
08 |
NetworkInfo networkInfo = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)) |
09 |
.getActiveNetworkInfo(); |
11 |
if (networkInfo != null ) { |
12 |
if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { |
14 |
String host = android.net.Proxy.getDefaultHost(); |
16 |
int port = android.net.Proxy.getDefaultPort(); |
17 |
if (host != null && port != - 1 ) { |
19 |
InetSocketAddress inetAddress = new InetSocketAddress(host, port); |
21 |
java.net.Proxy.Type proxyType = java.net.Proxy.Type.valueOf(urlURL.getProtocol().toUpperCase()); |
22 |
java.net.Proxy javaProxy = new java.net.Proxy(proxyType, inetAddress); |
23 |
httpConn = (HttpURLConnection) urlURL.openConnection(javaProxy); |
25 |
httpConn = (HttpURLConnection) urlURL.openConnection(); |
28 |
httpConn = (HttpURLConnection) urlURL.openConnection(); |
30 |
httpConn.setConnectTimeout(Const.NETWORK_OPEN_TIMEOUT); |
31 |
httpConn.setReadTimeout(Const.NETWORK_READ_TIMEOUT); |
32 |
httpConn.setDoInput( true ); |
36 |
} catch (NullPointerException npe) { |
38 |
} catch (MalformedURLException e) { |
40 |
} catch (IOException e) { |
由于需要设置Proxy的情况为使用运营商网络,所以代码一开始即使用通过Context获得ConnectivityManager,执行ConnectivityManager.getActiveNetworkInfo()获取当前可用的网络。在有可用网络的情况下,判断其类型,如果networkInfo.getType()返回值为ConnectivityManager.TYPE_MOBILE,则需要设置Proxy;在返回值为ConnectivityManager.TYPE_WIFI的情况下则跳过设置Proxy的步骤。
对HttpURLConnection设置Proxy需要指定代理IP及端口号,android.net.Proxy解决了这个问题。执行Proxy.getDefaultHost()和Proxy.getDefaultPort()将返回代理主机的IP及开放端口号,并以这两个信息传参构造InetSocketAddress。InetSocketAddress为IP套接地址,其主要形式可由IP地址与端口号组合而成,亦可用主机域名加端口号组合而成,这种情况下将尝试将主机域名解析为IP地址。
封装的方法openUrl()两个参数中第二个参数为网络链接地址,将该地址构造出URL实例后,使用URL.getProtocol()方法即可知该链接地址所使用的协议类型。使用得到的链接协议类型,执行java.net.Proxy.Type的valueOf()方法进一步得到所需Proxy.Type。
在InetSocketAddress及Proxy.Type确定的情况下,即可构造java.net.Proxy实例,执行代码为new java.net.Proxy(proxyType, inetAddress)。将新生成的Proxy对象做为参数,执行URL.openConnection(javaProxy),即可得到使用Proxy设置连接互联网的HttpURLConnection。