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);     }  }


                   

      

1 0
原创粉丝点击