刚接触java,写的一个并发访问网站计时的程序,总是捕捉到服务器返回不正确的状态码

主体类

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URLConnection;
import java.net.URL;
import java.util.concurrent.Executors;

import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.Reader;
import java.io.InputStreamReader;

import java.util.concurrent.*;

/**
 * 测试连接可用性的类
 * 功能:
 * 
 * 1·接受数据
 * 	接受用户输入的URL;
 * 	连接方式	;
 *  是否自动执行3**跳转;
 *  指定的是否登录的标记以及登录需要的账户、密码和登录页面;
 * 	用户指定的模拟并发数和单个并发的访问数;
 * 
 * 2·测试url是否可用
 * 	测试url的连接是否可以正常连接;
 * 
 * 3·获取url的相关信息
 * 	获取服务器的类型;
 * 	获取url的路径;
 * 	获取url内容长度;
 * 	获取url对应的ip地址
 * 
 * 4·获取登录信息
 *	获取登录需要的cookie	
 * 
 * */

public class GetHttpInfor {
	//基本参数
	private String urlToLink;//要连接的url
	private boolean  linkType;//连接的类型,为true则是http,为false则是https
	private boolean  requestType;//数据发送的方式,为true则是  get,为false则是post
	private int timeOut;	//设置超时时间限制
	private short condition;//url状态,通常为0 ,不通 为1;需要登录的页面无法获取cookie为 2 ;
	private int numForLink;//连接的次数
	private int numRequestForOne;//但是连接的请求数
	//登录页面参数
	private String urlToLogin;//登录所需的url
	private boolean linkTypeLogin;//登录页面的连接类型,为true则是http;为false则是https
	private boolean requestTypeLogin;//登录页面的数据发送类型,为true则是get,为false则是post
	private String username;//登录需要的账户
	private String poassword;//登录需要的密码
	private String cookie;//登录后获取到的cookie
	private int timeOutLogin;//登录页面的页面超时时间限制
	
	//url信息参数
	private String serviceType;//url的所对应的服务器类型
	private String path;//url的内容路径
	private String lenght;//url上内容的长度
	private String ip;//url对应的ip地址
	
	//并发请求时间
	private double allTime;//请求的总时间
	private double singleTime;//单个请求的时间
	
	//构造函数
	/**
	 * 获取用户传递的url,请求方式类型,请求的并发数和每个并发请求的次数
	 * 
	 * */
	
	GetHttpInfor(String urlTemp,String linkTypeTemp,int numForLink,int numRequestForOne,int timeOut){
		linkTypeTemp = linkTypeTemp.toLowerCase();
		String[] urlPieces = urlTemp.split("://");
		this.numForLink  = numForLink;
		this.numRequestForOne = numRequestForOne;
		this.urlToLink = urlTemp;
		this.timeOut = timeOut;
		 if(0==urlPieces[0].toLowerCase().compareTo("https")){
			this.linkType=false;
		}else{
			this.linkType=true;
			if(1==urlPieces[0].toLowerCase().compareTo("http")){
				this.urlToLink="http://"+this.urlToLink;
			}
		}
		 
		if(0==linkTypeTemp.compareTo("post")){
			this.requestType=false;
		}else{
			this.requestType=true;
		}
	}
	
	//设置是否登录
	/**
	 * 设置是否登录的开关量;设置登录的url,登录需要的用户名和密码
	 * 返回值:
	 * 成功获取登录状态,返回true
	 * 失败则返回false
	 * */
	public void login(String url,String requestTemp,int timeOutForLogin,String username,String password){
		//登录的初始化
		//从登录的url中获取连接的方式  http 或者 https
		
		String[] urlPieces = url.split("://");
		String strPost = "userid="+username+"&password="+password;
		
		if(0==urlPieces[0].toLowerCase().compareTo("https")){
			this.linkTypeLogin=false;
		}else{
			this.linkTypeLogin=true;
			if(1==urlPieces[0].toLowerCase().compareTo("http")){
				url = "http://"+url;
			}
		}
		
		//连接类型  get或者post
		if(0==requestTemp.toLowerCase().compareTo("post")){
			this.requestTypeLogin=false;
		}else{
			this.requestTypeLogin=true;
		}
		
		try {
			
			URL linkUrl = new URL(url);
			
			HttpURLConnection link =(HttpURLConnection)linkUrl.openConnection();
			if(!this.linkTypeLogin){
				link = (HttpsURLConnection)link;
			}			
			
			if(this.requestTypeLogin){
				link.setRequestMethod("POST");
			}else{
				link.setRequestMethod("GET");
			}
			//设置link 的属性,允许写输出
			link.setDoOutput(true);
			//设置link 的属性,允许读输入
			link.setDoInput(true);
			//设置link 的属性,允许使用缓存
			link.setUseCaches(false);
			//设置link 的属性,发送客户端的浏览器类型
			link.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Foxy/1; .NET CLR 2.0.50727; MEGAUPLOAD 1.0)");
			//设置link 的属性,目的主机
			link.setRequestProperty("Host", "http://acm.nyist.net/JudgeOnline/dologin.php?url=http%3A%2F%2Facm.nyist.net%2FJudgeOnline%2Fproblemset.php");
			//设置link 的属性,发送内容的长度
			link.setRequestProperty("Content-Length",strPost.length()+"");
			//设置link 的属性,连接的类型
			link.setRequestProperty("Connection", "Keep-Alive");
			//设置link 的属性
			link.setRequestProperty("Cache-Control", "no-cache");
			//设置link 的连接超时时间
			link.setConnectTimeout(timeOutForLogin);
			//输出内容到目的主机(发送用户的登录名和密码)
			link.getOutputStream().write(strPost.getBytes());
			link.getOutputStream().flush();
			link.getOutputStream().close();
			//设置此连接是否自动执行重定向
			link.setInstanceFollowRedirects(true);
			//执行连接
			link.connect();
			
			int code = link.getResponseCode();
			if(code!=200){
				this.condition = 2;
				this.cookie="";
				return;
			}
			this.cookie=link.getHeaderField("Set-Cookie");
			
			/*
			BufferedReader out = new BufferedReader(new InputStreamReader(link.getInputStream()));
			String oo = out.readLine();
			while(oo!=null){
				oo = new String(oo.getBytes("GBK"),"utf-8");
				System.out.println(oo);
				oo=out.readLine();
			}
			*/
		} catch (MalformedURLException e) {
			//url 连接不上
			this.condition = 2;
			this.cookie=null;
		} catch (IOException e){
			//获取url的连接内容出错
			this.condition = 2;
			this.cookie=null;
		}
	}
	
	//测试url是否可通
	/**
	 * 请求url页面,测试url是否可通;
	 * 记录服务器的类型,url的路径,url上内容的长度,url对应的ip地址;
	 * 并执行并发请求,记录请求的总时间、单个请求的时间
	 * 返回值:
	 * 若url请求不通,或者并发访问期间出现错误,返回false;
	 * url可通,且并发请求顺利完成,返回true;
	 * */
	
	public void test(){
		try{
			
			URL linkUrl = new URL(this.urlToLink);
			HttpURLConnection link = (HttpURLConnection)linkUrl.openConnection();
			if(!this.linkType){
				link = (HttpsURLConnection)link;
			}
			
			//设置相关参数
			//连接方式
			if(!this.requestType){
				link.setRequestMethod("POST");
			}else{
				link.setRequestMethod("GET");
			}
			
			//超时时间
			link.setConnectTimeout(this.timeOut);
			
			//是否携带cookie
			if(null!=this.cookie){
				link.setRequestProperty("Cookie",this.cookie);
			}
			//执行连接
			link.connect();
			
			//如果连接的页面连接不成功,则标记状态为1,并返回
			if(200!=link.getResponseCode()){
				this.condition = 1;
				return;
			}
			
			//记录url状态,连同测试同就认为是0
			this.condition = 0;
			
			//根据用户的模拟量要求申请线程池
			ExecutorService executor = Executors.newFixedThreadPool((this.numForLink/10)>1?this.numForLink:1);
			
			//获取各种记录各种状态值的类对象
			
			NumAcc numAcc = NumAcc.getNumAcc();
			NumNoFound numNoFound = NumNoFound.getNumNoFound();
			NumTimeout numTimeout = NumTimeout.getNumTimeout();
			NumOther numOther = NumOther.getNumOther();
			
			NumSignel numSignel = NumSignel.getNumSignel();
			numSignel.numSignel=this.numForLink*this.numRequestForOne;
			
			//创建线程类的实例对象
			LinkThread[] runFoundation = new LinkThread[this.numForLink];
			Thread[] thread= new Thread[this.numForLink];
			for(short i= 0; i<runFoundation.length;i++){
				runFoundation[i] = new LinkThread(this.urlToLink,this.numRequestForOne,this.linkType,this.requestType,this.timeOut,this.cookie,numAcc,numNoFound,numTimeout,numOther,numSignel);
				thread[i]=new Thread(runFoundation[i]);
			}
			runFoundation=null;
			
			//记录当前时间,将线程加入到线程池中
			long  startTime = System.currentTimeMillis();
			for(short i = 0;i<thread.length;i++){
				executor.execute(thread[i]);
			}
			executor.shutdown();
			//记录结束时间,计算总时间
			while(numSignel.numSignel!=0){
				//System.out.println(numSignel.numSignel);
			}
			//结束时间
			long endTime = System.currentTimeMillis();
			
			System.out.println(startTime+"----"+endTime);
			
			System.out.println("numAcc: "+numAcc.numAcc+" -- numNoFound:"+numNoFound.numNoFound+" -- numTimeout:"+numTimeout.numTimeout+" -- numOther:"+numOther.numOther);
		}catch(IOException e){
			//url不通的时候的错误处理
			this.condition = 1;
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		GetHttpInfor one = new GetHttpInfor("http://www.php100.com/","get",20,30,5000);
		one.test();
	}
}

然后是线程类


import java.io.IOException;
import java.net.HttpURLConnection;
import javax.net.ssl.HttpsURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.*;

/**
 * 线程函数,
 * 接受传递过来的参数,模拟连接访问
 * 
 * */

public class LinkThread implements Runnable{
	
	private String url;//要连接的url
	private boolean linkType;//连接的方式
	private boolean requestType;//请求的方式
	private int timeOut;//记录请求超时的时间
	private String cookie;//cookie 的值
	private int num;//请求次数
	
	private NumAcc numAcc;//记录200 请求的对象
	private NumNoFound numNoFound;//记录404 请求的对象
	private NumTimeout numTimeout;//记录超时的请求对象
	private NumOther numOther;//记录其他请求状态的对象
	private NumSignel numSignel;//
	
	/**
	 * 接收 url , num-访问次数,linktype 访问类型(http/https),requesttype  请求类型(get/post),cookie--登录用的cookie 
	 * numAcc--请求正常的状态记录对象(200),numNoFound--页面未找到的状态记录对象(404),numTimeout--超时的状态记录对象(其实没有用,不知道什么时候才算超时),numOther--之外的状态记录对象
	 * numSingel--线程数量的记录对象 用于获取线程全部请求完毕这个状态
	 * */
	LinkThread(String url,int num,boolean linkType,boolean RequestType,int timeOut,String cookie,NumAcc numAcc,NumNoFound numNoFound,NumTimeout numTimeout,NumOther numOther,NumSignel numSignel){
		this.url=url;
		this.linkType=linkType;
		this.requestType=requestType;
		this.timeOut=timeOut;
		this.cookie=cookie;
		this.num=num;
		this.numAcc=numAcc;
		this.numNoFound=numNoFound;
		this.numOther=numOther;
		this.numSignel=numSignel;
	}
	
	/**
	 * 线程执行的主体
	 * 模拟一次并发的多次访问,并记录每次请求返回的状态
	 * 
	 * */
	public void run(){
		try{
			while(0!=this.num--){
				URL linkUrl = new URL(this.url);
				HttpURLConnection link = (HttpURLConnection)linkUrl.openConnection();
				if(!this.linkType){
					link = (HttpsURLConnection)link;
				}
				//设置参数
				if(!this.requestType){
					link.setRequestMethod("POST");
				}else{
					link.setRequestMethod("GET");
				}
				link.setConnectTimeout(this.timeOut);
				if(null!=this.cookie){
					link.setRequestProperty("cookie", this.cookie);
				}
				//执行连接
				link.connect();
				
				//状态记录
				System.out.println(link.getResponseCode());
				if(200==link.getResponseCode()){
					synchronized(this.numAcc){
						this.numAcc.numAcc++;
					}
				}else if(404==link.getResponseCode()){
					synchronized(this.numNoFound){
						this.numNoFound.numNoFound++;
					}
				}else{
					synchronized(this.numOther){
						this.numOther.numOther++;
					}
				}
				//减去一个线程的计数
				synchronized(this.numSignel){
					this.numSignel.numSignel--;
				}
			}
		}catch(IOException e){
			synchronized(this.numOther){
				this.numOther.numOther++;
			}
		}
	}
}

还有几个状态记录的类


/**
 * 	numAcc
 * 	记录200状态的请求次数
**/
public class NumAcc{
	public int numAcc;
	private static  NumAcc object = new NumAcc();
	private NumAcc(){
		this.numAcc=0;
	}
	public static  NumAcc getNumAcc(){
		return object;
	}
}

/**
 *	numnoFoun 
 *	记录404状态的请求次数
 **/
class NumNoFound{
	public int numNoFound;
	private static  NumNoFound  object = new NumNoFound();
	private NumNoFound(){
		this.numNoFound=0;
	}
	public static  NumNoFound getNumNoFound(){
		return object;
	}
}

/**
 * numOther
 * 记录其它状态的请求次数
 * */
class NumOther{
	public int numOther;
	private static  NumOther object = new NumOther();
	private NumOther(){
		this.numOther=0;
	}
	public static  NumOther getNumOther(){
		return object;
	}
}

/**
 * NumSignel
 * 创建的线程数
 * */
class NumSignel{
	public int numSignel;
	private static  NumSignel object = new NumSignel();
	private NumSignel(){
		this.numSignel=0;
	}
	public static  NumSignel getNumSignel(){
		return object;
	}
}

/**
 * numTimeout
 * 记录超时的请求次数
 * */
class NumTimeout{
	public int numTimeout;
	private static  NumTimeout object = new NumTimeout();
	private NumTimeout(){
		this.numTimeout=0;
	}
	public static  NumTimeout getNumTimeout(){
		return object;
	}
}

不知道为什么,

请求总是返回405状态码,

说请求的方式不对,

程序里不是已经确定是get请求了,

为什么会出这个状态码??

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值