android Http通信局域网测试详解
来源:互联网 发布:知不足者好学的下一句 编辑:程序博客网 时间:2024/05/17 23:21
以前一直用别人的服务器感觉特别别扭,而且一直受制于人。有句话怎么说“自己动手丰衣足食”,最近对Node.js,express框架以及javascript服务器搭建有些许研究,通过两天的研究终于搭建起自己的服务器,这个服务器搭建过程在这鄙人就不一一细说了,如果有需要的可以留言一起探讨。
经过不懈的努力终于有了自己的服务器,在这呢我用了两种测试的方法,(1).在PC机上进行测试,(2).在局域网中通过android小DEMO测试接下来呢就详细对其进行讲解。
在局域网中测试的时候一定要先ping通自己的网络,如果网络能够ping通却请求不会数据来,在这给你几种解决方法:
(1).将电脑上的无线热点打开,让手机连接上此热点,这样电脑就相当于路由器,用电脑的ip地址就可以通信了。
(2).对路由器就行无线网络共享数据设置,否则连上同一个路由器是不会通的。
(3).自己用花生卡申请一个IP地址,把自己的IP地址映射到外网上就可以访问了。
一.在PC机上进行测试详细步骤
(1).在测试之前一定要ping通IP地址,只有两者通了才能进行数据交互,否则一切都妄谈。
废话不多说了直接上图,:
(2).在Eclipse中建立一个Java项目,建一个MainActivity.java的类,然后在里面写入下面的代码就OK了,代码中注释写的明明白白了。
public class MainActivity {
public static String excute(){
// 服务器的IP地址和端口号
String url = "http://localhost:3000/hellos";
// 通过HttpResultData去请求数据
return HttpResultData.getData(url);
}
public static void main(String[] args) {
// 将请求的数据保存下来
String result = excute();
System.out.println(result);
}
}
(3).在建立一个向Http请求数据的类,大家都知道java是一个面向的对象的编程语言,所以大家一定要采用面向对象的思想的去写代码,这样有助于提高代码的重用率,不是说高内聚低耦合吗。在这呢就直接上代码了:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
/**
* @author 何斌
* 功能:访问网络的类,对get和post方法进行了封装
*
*/
public class HttpResultData {
/**
* get方法直接调用post方法
* @param url 网络地址
* @return 返回服务器请求回来的数据
*/
public static String getData(String url){
return postData(url, null);
}
/**
* 设定post方法获取网络资源,如果参数为null,实际上设定为get方法
* @param url 网络地址
* @param param 请求参数键值对
* @return 返回读取数据
*/
@SuppressWarnings("rawtypes")
public static <Key, Value> String postData(String url,Map<Key, Value> param){
System.out.println("HttpResultData----postData");
// 创建一个HttpURLConnection对象,用于连接指定站定
HttpURLConnection conn = null;
try {
// 创建一个URL对象,并绑定相应的站点
URL u = new URL(url);
// 打开于站点的连接
conn = (HttpURLConnection) u.openConnection();
// 创建一个缓冲区,用于存放请求回来的数据
StringBuffer sb = null;
// 如果请求参数不为空
if(param != null){
sb = new StringBuffer();
// 默认为false,post方法需要写入参数,设定true
conn.setDoOutput(true);
// 设定post方法,默认get
conn.setRequestMethod("POST");
// 获得输出流
OutputStream out = conn.getOutputStream();
// 对输出流封装成高级输出流
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
// 将参数封装成键值对的形式
for(Map.Entry s: param.entrySet()){
sb.append(s.getKey()).append("=").append(s.getValue()).append("&");
}
//将参数通过输出流写入
writer.write(sb.deleteCharAt(sb.toString().length()-1).toString());
writer.close();//一定要关闭,不然可能出现参数不全的错误
sb=null;
}
conn.connect();//建立连接
System.out.println("jffffffffff");
sb=new StringBuffer();
//获取连接状态码
int recode = conn.getResponseCode();
System.out.println("jffffffffff"+recode);
BufferedReader reader=null;
if(recode == 200){
//Returns an input stream that reads from this open connection
//从连接中获取输入流
InputStream in = conn.getInputStream();
//对输入流进行封装
reader=new BufferedReader(new InputStreamReader(in));
String str=null;
sb = new StringBuffer();
//从输入流中读取数据
while((str = reader.readLine())!=null){
System.out.println("HttpResultData----postData" + str);
sb.append(str).append(System.getProperty("line.separator"));
}
//关闭输入流
reader.close();
if (sb.toString().length() == 0) {
return null;
}
return sb.toString().substring(0,
sb.toString().length() - System.getProperty("line.separator").length());
}
} catch (Exception e) {
e.printStackTrace();
return null;
}finally{
if(conn!=null)//关闭连接
conn.disconnect();
}
return null;
}
}
(4).运行截图
二.在android手机上测试详细步骤
(1).首先在Eclipse中建立工程,在这就不详细讲解了。
(2).在AndroidManifest..xml中加上网络访问权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
(3).在Layout文件中这样布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parent_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textview_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</FrameLayout>
<Button
android:id="@+id/btn_visit_web"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:text="点击请求数据" />
</RelativeLayout>
(4).在MainActivity中写下面的代码就可以,代码注释都写的明明白白的了。
package com.example.hellow;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity {
Button visitWebBtn = null;
TextView showTextView = null;
String resultStr = "";
ProgressBar progressBar = null;
ViewGroup viewGroup = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().
detectDiskWrites().detectNetwork().penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().
detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
// 绑定显示的布局
setContentView(R.layout.activity_main);
// 初始化控件
initUI();
// 为控件设置监听者
visitWebBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// 设置显示文本控件可见
showTextView.setVisibility(View.VISIBLE);
// 创建一个线程对象,并绑定方法
Thread visitBaiduThread = new Thread(new VisitWebRunnable());
// 启动线程
visitBaiduThread.start();
try {
visitBaiduThread.join();
// 如果请求会的数据不为null
if(!resultStr.equals("")){
// 将数据显示到文本控件上
showTextView.setText(resultStr);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public void initUI(){
showTextView = (TextView)findViewById(R.id.textview_show);
visitWebBtn = (Button)findViewById(R.id.btn_visit_web);
}
/**
* 获取指定URL的响应字符串
* @param urlString
* @return
*/
private String getURLResponse(String urlString){
// 连接对象
HttpURLConnection conn = null;
// 创建输入流对象
InputStream is = null;
// 创建一个局部变量保存放回的数据
String resultData = "";
try {
//URL对象
URL url = new URL(urlString);
//使用URL打开一个链接
conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
// //允许输出流,即允许上传
// conn.setDoOutput(true);
//不使用缓冲
conn.setUseCaches(false);
//使用get请求
conn.setRequestMethod("GET");
//获取输入流,此时才真正建立链接
is = conn.getInputStream();
// 对输入流就行包装
InputStreamReader isr = new InputStreamReader(is);
// 用输入流对象创建一个缓冲区
BufferedReader bufferReader = new BufferedReader(isr);
String inputLine = "";
Log.i("????????????/", inputLine+"??????????");
while((inputLine = bufferReader.readLine()) != null){
Log.i("????????????/", inputLine+"??????????");
resultData += inputLine + "\n";
}
Log.i("????????????/", resultData+"??????????");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(conn != null){
conn.disconnect();
}
}
return resultData;
}
class VisitWebRunnable implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
String data = getURLResponse("http://192.168.1.111:3000/hellos");
Log.i(">>>>>>>>>>>>", data);
resultStr = data;
}
}
}
在此服务器测试就讲解完了,但是再测中肯定不会一帆风顺,在这儿呢我就把几个常见的问题跟大家分享一下:
(1).如果错误原因是主机地址为"NULL",那就是你的IP地址根本就不同,此时你就的用上面提到的方法。
(2).跑了一下自己的app,发现下载xml文件部分抛出异常:java.io.FileNotFoundException:
解决方法:
原因:
4.0中设置conn.setDoOutput(true),将导致请求以post方式提交,即使设置了conn.setRequestMethod("GET");
将代码中的conn.setDoOutput(true);删除即可
(3).Caused by:android.os.NetworkOnMainThread查了下原因上在4.0之后在主线程里面执行Http请求都会报这个错,也许是怕Http请求时间太长造 成程序假死的情况吧。
在这介绍两种解决方法:
第一种:直接忽视,强制使用(强烈不推荐,但是修改简单)
在MainActivity文件的setContentView(R.layout.activity_main)下面加上如下代码
if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); }
第二种::使用Thread、Runnable、Handler (推荐使用)在Runnable中做HTTP请求,不用阻塞UI线程~public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.share_mblog_view); new Thread(runnable).start(); } Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bundle data = msg.getData(); String val = data.getString("value"); Log.i("mylog","请求结果-->" + val); } } Runnable runnable = new Runnable(){ @Override public void run() {Message msg = new Message(); Bundle data = new Bundle(); data.putString("value","请求结果"); msg.setData(data); handler.sendMessage(msg); } }
- android Http通信局域网测试详解
- android Http通信开发详解
- 【Android】socket局域网通信
- android局域网通信( 一)
- android局域网通信(二)
- android局域网通信(三)
- Android的HTTP协议的通信详解
- Android模拟器与局域网通信
- Android之基于HTTP协议的通信详解
- Android之基于HTTP协议的通信详解
- 【移动开发】Android之基于HTTP协议的通信详解
- Android之基于HTTP协议的通信详解
- Android之基于HTTP协议的通信详解
- android局域网通信(udp,tcp等)
- Android开发局域网通信软件笔记
- Android 局域网通信异常--引申自Java
- android局域网内通过socket通信
- 使用Coap实现android 局域网通信
- P25 (*) Generate a random permutation of the elements of a list.
- [Leetcode] 98. Validate Binary Search Tree @python
- 模版方法模式
- 2015年第六届蓝桥杯C/C++程序设计本科B组省赛 牌型种数(结果填空)
- js的作用域学习笔记
- android Http通信局域网测试详解
- Ubuntu12.04安装中文输入法
- 快慢指针------Linked List Cycle
- 用SlidingMenu实现仿QQ侧滑+Viewpage+ListView多布局
- web应用程序的目录结构
- Android学习-ListView+ CheckBox实现单选
- OC基础之Category,Extension,Protocol
- 如何将tomcat服务器启动端口改为80
- 自动重置事件练习