具体内容就不说了,只是自己留着未来好找而已

主窗体:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MaoYoo.ChinaMobile.Core;
using System.Net;
using System.IO;
using System.Configuration;
using System.Threading;
using System.Text.RegularExpressions;
using MaoYoo.ChinaMobile.DataObject;
using MaoYoo.ChinaMobile.Core.PropertyGridUI;
using System.Drawing.Design;
using System.Reflection;
using System.IO.Compression; namespace MaoYoo.ChinaMobile
{
public partial class frmMain : Form
{
PropertyParameters paramters = new PropertyParameters(); public frmMain()
{
InitializeComponent();
this.progressBar.Step = 1; this.propertyParameterGrid.SelectedObject = paramters;
} private void btnExecute_Click(object sender, EventArgs e)
{
this.progressBar.Value = 0;
this.listViewMonitor.Items.Clear();
this.btnExecute.Enabled = false; if (paramters.File == null || string.IsNullOrEmpty(paramters.File.Trim()) || !File.Exists(paramters.File))
{
MessageBox.Show("请选择正确的数据文件!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
} #region 加载数据并清除全部结果
Aspose.Cells.Workbook workBook = new Aspose.Cells.Workbook();
workBook.Open(paramters.File); Aspose.Cells.Worksheet sheet = workBook.Worksheets[0]; AsposeExcelHelper.InitializeExcel(paramters.File); int iMaxRowsCount = 0; while (true)
{
if (string.IsNullOrEmpty(sheet.Cells[iMaxRowsCount, 0].StringValue.Trim()))
{
break;
}
// 将数据添加至队列中
MessageQueueHelper.WaitingQueue.Enqueue(sheet.Cells[iMaxRowsCount, 0].StringValue.Trim()); iMaxRowsCount++; Application.DoEvents();
} this.progressBar.Maximum = iMaxRowsCount;
#endregion
#region 分配线程池工作任务
for (int i = 0; i < paramters.Thread; i++)
{
ThreadStatus thread = new ThreadStatus();
thread.Index = i;
thread.Paramteter = paramters;
ListViewItem item = new ListViewItem(i.ToString());
item.SubItems.Add("就绪");
item.SubItems.Add("0");
listViewMonitor.Items.Add(item); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCallBack), thread); Application.DoEvents();
}
#endregion #region 判断ThreadPool执行结束
while (true)
{
int maxWorkerThreads, workerThreads;
int portThreads; ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
MessageBox.Show("数据查询完成!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
this.btnExecute.Enabled = true;
break;
}
Application.DoEvents(); Thread.Sleep(100);
}
#endregion
} void ThreadPoolCallBack(object obj)
{
#region 异常问题
Control.CheckForIllegalCrossThreadCalls = false; ThreadStatus status = obj as ThreadStatus;
#endregion while (MessageQueueHelper.WaitingQueue.Count > 0)
{
try
{
#region 执行网站查询动作
// 取出要查询的业务手机号码
string mobile = MessageQueueHelper.WaitingQueue.Dequeue(); this.listViewMonitor.Items[status.Index].SubItems[1].Text = string.Format("正在查询号码:{0} 账号{1}", mobile, AccessOperatorAdapter.Instance.CurrentOperator.UserName);
Application.DoEvents(); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.RequestQuery"]);
request.Proxy = null;
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip"); request.Method = "POST";
request.ServicePoint.UseNagleAlgorithm = false;
request.ServicePoint.ConnectionLimit = 65535;
request.AllowWriteStreamBuffering = false;
request.CookieContainer = AccessOperatorAdapter.Instance.CurrentOperator.OperatorCookieContainer; request.ContentType = "application/x-www-form-urlencoded"; byte[] buffer = Encoding.Default.GetBytes(string.Format("bill_id={0}&submit=submit&bill_id1=", mobile)); request.ContentLength = buffer.LongLength; using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
} HttpWebResponse response = (HttpWebResponse)request.GetResponse(); string content = string.Empty; if (response.ContentEncoding.ToLower().Contains("gzip"))
{
using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (StreamReader sr = new StreamReader(stream, Encoding.Default))
{
content = sr.ReadToEnd();
}
}
}
else if (response.ContentEncoding.ToLower().Contains("deflate"))
{
using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
{
using (StreamReader sr = new StreamReader(stream, Encoding.Default))
{
content = sr.ReadToEnd();
}
}
}
else
{
using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default))
{
content = sr.ReadToEnd();
}
} #endregion #region 初始化临时变量 #endregion // 验证查询次数
AccessOperatorAdapter.Instance.ValidateOperatorMaximumQuery(content); if (!AccessOperatorAdapter.Instance.CurrentOperator.MaximumQuery)
{
Array.ForEach<string>(status.Paramteter.Conditions, target =>
{
if (content.IndexOf(target) >= 0)
{
WS4Response mResponse = new WS4Response(); // 反射获取全部读取内容
Type objType = typeof(WS4Response); foreach (PropertyInfo propInfo in objType.GetProperties())
{
object[] attrs = propInfo.GetCustomAttributes(typeof(ResultAttribute), true); if (attrs.Length > 0)
{
ResultAttribute attr = attrs[0] as ResultAttribute; if (attr != null)
{
Match match = Regex.Match(content, attr.RegexExpression, RegexOptions.IgnoreCase | RegexOptions.Multiline); if (match.Success)
{
if (match.Groups.Count > 0)
{
try
{
propInfo.SetValue(mResponse, Convert.ChangeType(match.Groups[1].Value, attr.DataType), null);
}
catch
{ }
}
}
}
}
} #region 写入Excel并更新窗体界面
if (((status.Paramteter.Enabled) && (status.Paramteter.Balance <= mResponse.Amount)) || !status.Paramteter.Enabled)
{
AsposeExcelHelper.WriteAsposeExcel(status.Paramteter.File,
target, mResponse); int currentIndex = 0; currentIndex = (int)Convert.ChangeType(
listViewMonitor.Items[status.Index].SubItems[2].Text, typeof(int)); listViewMonitor.Items[status.Index].SubItems[2].Text = (currentIndex + 1).ToString();
Application.DoEvents();
}
#endregion
}
});
}
}
catch { } this.progressBar.PerformStep();
this.label1.Text = string.Format("{0} / {1}", this.progressBar.Value, this.progressBar.Maximum);
Application.DoEvents();
Thread.Sleep(100);
}
Application.DoEvents();
} /// <summary>
/// 得到某一个对象的某个属性的DataProperty的描述
/// </summary>
/// <param name="oData"></param>
/// <param name="strPropertyName"></param>
/// <returns></returns>
public static ResultAttribute GetResultpropertyFromContext(object oData, string strPropertyName)
{
PropertyInfo[] piArray = oData.GetType().GetProperties(BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
ResultAttribute dpa = null;
for (int i = 0; i < piArray.Length; i++)
{
PropertyInfo pi = piArray[i];
if (pi.Name.Equals(strPropertyName, StringComparison.OrdinalIgnoreCase))
{
dpa = (ResultAttribute)Attribute.GetCustomAttribute(pi, typeof(ResultAttribute));
break;
}
}
return dpa;
}
} public class ThreadStatus
{
/// <summary>
/// 线程编号
/// </summary>
public int Index
{
get;
set;
} public PropertyParameters Paramteter
{
get;
set;
}
} #region 参数面板设计
public class PropertyParameters
{
[Category("余额")]
[Description("是否启用余额")]
[DisplayName("余额匹配")]
[ReadOnlyAttribute(false), Browsable(true)]
public bool Enabled
{
get { return mEnabledBalance; }
set
{
PropertyGridHelper.SetPropertyValue<ReadOnlyAttribute>(this, "Balance", "isReadOnly", !value);
mEnabledBalance = value; }
} private bool mEnabledBalance = true; [Category("余额")]
[DefaultValue(typeof(decimal), "0.00")]
[DisplayName("账户余额")]
[Description("需要查询的用户账户余额")]
public decimal Balance
{
get { return mBalance; }
set
{ mBalance = value;
}
}private decimal mBalance = decimal.Zero; [Category("线程")]
[Description("最大执行线程数量")]
[DisplayName("线程数量")]
[ReadOnlyAttribute(false), Browsable(true)]
public int Thread
{
get { return _thread; }
set { _thread = value; }
} private int _thread = 10; [Category("文件")]
[DisplayName("数据文件")]
[Description("用户数据列表文件路径")]
[ReadOnlyAttribute(false), Browsable(true)]
[Editor(typeof(PropertyGridFileSelector), typeof(UITypeEditor))]
public string File
{
get;
set;
} [Category("查询")]
[DisplayName("查询条件")]
[Description("查询条件列表")]
[ReadOnlyAttribute(false), Browsable(true)]
public string[] Conditions
{
get;
set;
}
}
#endregion
}

自动切换账号:

using System;
using System.Collections.Generic;
using System.Text;
using MaoYoo.ChinaMobile.DataObject; namespace MaoYoo.ChinaMobile
{
public class AccessOperatorAdapter
{
private AccessOperatorAdapter() { } private static AccessOperatorAdapter instance = new AccessOperatorAdapter(); private static Operator CurrentRequestOperator = new Operator("XXX", "XXX"); public static AccessOperatorAdapter Instance
{
get
{
return instance;
}
} public void ValidateOperatorMaximumQuery(string content)
{
CurrentRequestOperator.MaximumQuery = content.IndexOf("查询次数已达上限") >= 0;
} public Operator CurrentOperator
{
get
{ if (OperatorCache.OperatorQueue.Count > 0)
{
if (CurrentRequestOperator == null || CurrentRequestOperator.MaximumQuery || !CurrentRequestOperator.IsAuthentication)
{
// 获取一个新的Operator
Operator user = OperatorCache.OperatorQueue.Peek();
user.ValidateAuthentication();
OperatorCache.OperatorQueue.Dequeue();
CurrentRequestOperator = null;
if (user.IsAuthentication)
{
CurrentRequestOperator = user;
return CurrentRequestOperator;
}
else
{ return CurrentOperator;
} }
else
{
return CurrentRequestOperator;
}
}
else
{
throw new Exception("无可用的账号!");
}
} }
}
}

响应结果定义:

using System;
using System.Collections.Generic;
using System.Text; namespace MaoYoo.ChinaMobile.DataObject
{
public class WS4Response
{
public WS4Response()
{
} /// <summary>
/// 号码
/// </summary>
[Result(RegexExpression = "号码:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string Number
{
get;
set;
} /// <summary>
/// 前三个月平均消费
/// </summary>
[Result(RegexExpression = "平均消费:(.+?)</td>", DataType = typeof(decimal), DataFormatString = "")]
public decimal ConsumptionBeforeQuarter
{
get;
set;
} /// <summary>
/// 终端品牌
/// </summary>
[Result(RegexExpression = "终端品牌:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string TerimalBrand
{
get;
set;
} /// <summary>
/// 在网月数
/// </summary>
[Result(RegexExpression = "在网月数:(.+?)</td>", DataType = typeof(int), DataFormatString = "")]
public int NetInMonths
{
get;
set;
} /// <summary>
/// 更新日期
/// </summary>
[Result(RegexExpression = "更新日期:(.+?)</td>", DataType = typeof(DateTime), DataFormatString = "yyyyMMdd")]
public DateTime UpdateDateTime
{
get;
set;
} /// <summary>
/// 账户余额
/// </summary>
[Result(RegexExpression = "账户余额:(.+?)</td>", DataType = typeof(decimal), DataFormatString = "")]
public decimal Amount
{
get;
set;
} /// <summary>
/// 终端使用月数
/// </summary>
[Result(RegexExpression = "终端使用月数:(.+?)</td>", DataType = typeof(int), DataFormatString = "")]
public int TerimalMonthUsed
{
get;
set;
} /// <summary>
/// 本月流量
/// </summary>
[Result(RegexExpression = "本月流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
public decimal CurrentMonthFlow
{
get;
set;
}
/// <summary>
/// 本月超出流量费
/// </summary>
[Result(RegexExpression = "本月超出流量费(截止前日供参考):(.+?)元;", DataType = typeof(decimal), DataFormatString = "")]
public decimal CurrentMonthOverFlow
{
get;
set;
} /// <summary>
/// 上月流量
/// </summary>
[Result(RegexExpression = "上月流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
public decimal PreivousMonthFlow
{
get;
set;
} /// <summary>
/// 前三个月平均流量
/// </summary>
[Result(RegexExpression = "前三个月平均流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
public decimal PreviousQuoterFlow
{
get;
set;
} /// <summary>
/// 本月套餐
/// </summary>
[Result(RegexExpression = "本月套餐:(.+?);", DataType = typeof(string), DataFormatString = "")]
public string CurrentMonthPackage
{
get;
set;
} /// <summary>
/// 上月夜间流量
/// </summary>
[Result(RegexExpression = "上月夜间流量(.+?)M</td>", DataType = typeof(decimal), DataFormatString = "")]
public decimal PreviousMonthNightFlow
{
get;
set;
} /// <summary>
/// 智能终端标识
/// </summary>
[Result(RegexExpression = "智能终端标志:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string SmartTermial
{
get;
set;
} /// <summary>
/// 四星客户标志
/// </summary>
[Result(RegexExpression = "四星客户标志:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string Customer4Start
{
get;
set;
} /// <summary>
/// 叠加保底情况
/// </summary>
[Result(RegexExpression = "当前保底:(.+?)</td> ", DataType = typeof(string), DataFormatString = "")]
public string SuperposionOfSituation
{
get;
set;
} /// <summary>
/// 虚拟网
/// </summary>
[Result(RegexExpression = "虚拟网:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string VirtualNetwork
{
get;
set;
} /// <summary>
/// 亲情网
/// </summary>
[Result(RegexExpression = "亲情网:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
public string FamilyNetwork
{
get;
set;
}
}
}

账户自定义类:

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Configuration;
using System.IO; namespace MaoYoo.ChinaMobile.DataObject
{
public class Operator
{
public Operator(string name, string pass)
{
this.UserName = name;
this.Password = pass;
this.MaximumQuery = false;
this.IsAuthentication = false;
} /// <summary>
/// 账号
/// </summary>
public string UserName
{
get;
set;
}
/// <summary>
/// 密码
/// </summary>
public string Password
{
get;
set;
}
/// <summary>
/// 超过最大查询限制
/// </summary>
public bool MaximumQuery
{
get;
set;
} /// <summary>
/// 是否账号经过身份验证
/// </summary>
public bool IsAuthentication
{
get;
private set;
} /// <summary>
/// 验证登录账号合法性
/// </summary>
public void ValidateAuthentication()
{
if (OperatorCookieContainer == null)
OperatorCookieContainer = new CookieContainer(); try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.AccessLogon"]);
request.Proxy = null;
request.Method = "POST";
request.UserAgent = ConfigurationManager.AppSettings["CM.UserAgent"];
request.CookieContainer = this.OperatorCookieContainer;
request.ContentType = "application/x-www-form-urlencoded"; byte[] buffer = Encoding.Default.GetBytes(string.Format("id_name={0}&id_pwd={1}&flag=1&sub=submit", this.UserName, this.Password)); request.ContentLength = buffer.LongLength; #region 向HTTP请求写入POST数据
using (Stream stream = request.GetRequestStream())
{
stream.Write(buffer, 0, buffer.Length);
}
#endregion #region 响应结果,为保存CookieContainer
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
#endregion #region 验证登陆
// 有Cookie数据保存至模拟的浏览器
if (OperatorCookieContainer.Count > 0)
{
//HttpWebRequest mRequest = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.AccessToken"]); //mRequest.Method = "GET";
//mRequest.CookieContainer = this.OperatorCookieContainer;
//mRequest.UserAgent = ConfigurationManager.AppSettings["CM.UserAgent"]; //using (HttpWebResponse mResponse = (HttpWebResponse)mRequest.GetResponse())
//{
// using (StreamReader sr = new StreamReader(mResponse.GetResponseStream(),Encoding.Default))
// {
// string content = sr.ReadToEnd(); // if (content.IndexOf(ConfigurationManager.AppSettings["CM.AccessValidate"]) >= 0)
// {
this.IsAuthentication = true;
// }
// }
//}
}
#endregion
}
catch
{
this.IsAuthentication = false;
}
} /// <summary>
/// 操作员Cookie容器
/// </summary>
public CookieContainer OperatorCookieContainer
{
get;
private set;
}
}
}

集线程池应用、多次HttpWebRequest请求,自动切换账号等等的移动信息查询软件的更多相关文章

  1. 自定义ThreadPoolExecutor带Queue缓冲队列的线程池 + JMeter模拟并发下单请求

    .原文:https://blog.csdn.net/u011677147/article/details/80271174 拓展: https://github.com/jwpttcg66/GameT ...

  2. .NET 线程池编程技术

    摘要 深度探索 Microsoft .NET提供的线程池, 揭示什么情况下你需要用线程池以及 .NET框架下的线程池是如何实现的,并告诉你如何去使用线程池. 内容 介绍 .NET中的线程池 线程池中执 ...

  3. 线程池(ThreadPool)

    线程池概述 由系统维护的容纳线程的容器,由CLR控制的所有AppDomain共享.线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 线程池与线程 性能:每开启一个新 ...

  4. elasticsearch高级配置二----线程池设置

    一个Elasticsearch节点会有多个线程池,但重要的是下面四个: 索引(index):主要是索引数据和删除数据操作(默认是cached类型) 搜索(search):主要是获取,统计和搜索操作(默 ...

  5. Socket Server-基于线程池的TCP服务器

    了解线程池 在http://blog.csdn.net/ns_code/article/details/14105457(读书笔记一:TCP Socket)这篇博文中,服务器端采用的实现方式是:一个客 ...

  6. 线程池ThreadPool的初探

    一.线程池的适用范围 在日常使用多线程开发的时候,一般都构造一个Thread示例,然后调用Start使之执行.如果一个线程它大部分时间花费在等待某个事件响应的发生然后才予以响应:或者如果在一定期间内重 ...

  7. Java线程池的那些事

    熟悉java多线程的朋友一定十分了解java的线程池,jdk中的核心实现类为java.util.concurrent.ThreadPoolExecutor.大家可能了解到它的原理,甚至看过它的源码:但 ...

  8. Linux下线程池的理解与简单实现

    首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池. 其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程 ...

  9. 线程池之ThreadPool类与辅助线程 - <第二篇>

    一.CLR线程池 管理线程开销最好的方式: 尽量少的创建线程并且能将线程反复利用(线程池初始化时没有线程,有程序请求线程则创建线程): 最好不要销毁而是挂起线程达到避免性能损失(线程池创建的线程完成任 ...

  10. elasticsearch高级配置之(二)----线程池设置

    elasticsearch 配置 线程池  一个Elasticsearch节点会有多个线程池,但重要的是下面四个:  索引(index):主要是索引数据和删除数据操作(默认是cached类型)  搜索 ...

随机推荐

  1. PYQT搭建相关记录

    class Demo(QWidget): def __init__(self): super(Demo, self).__init__() # 设置标题 icon 尺寸 self.setWindowT ...

  2. windows10环境下的RabbitMQ安装步骤(图文)(转载)

    第一步:下载并安装erlang 原因:RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang. 下载地址:http://www.erlang.or ...

  3. 区块链技术与应用:02-BTC-密码学原理

    本文为个人整理笔记,知识点来源于北京大学肖臻老师的<区块链技术与应用>公开课视频:https://www.bilibili.com/video/BV1Vt411X7JF?from=sear ...

  4. 《MySQL是怎样运行的》第二章小结

  5. 脏牛-Linux内核提权

    漏洞范围 下载地址:https://github.com/FireFart/dirtycow 有一点可以在意,dirty.c内置在了kali中,使用命令searchsploit dirty可以搜索 也 ...

  6. 全网最详细中英文ChatGPT接口文档(一)开始使用ChatGPT——导言

    目录 Introduction 导言 Overview 概述 Key concepts 关键概念 Prompts and completions 提示和完成 Tokens 标记/符号 Models 模 ...

  7. 19.new和delete用于数组

    程序1: //2022年9月20日22:06:27 #include <iostream> #pragma warning(disable:4996) using namespace st ...

  8. .Net7 CLR的调用函数和编译函数

    前言 .Net运行模型,无非就两个过程.一个是调用入口函数,另外一个就是编译入口函数.前者主调用,后者主编译. 概括 一:入口函数:RunMainInternal 所有的.Net程序,包括控制台,We ...

  9. 前端开发工具 VS Code 安裝及使用

    一.下载地址 https://code.visualstudio.com/ 下载完后,傻瓜式安装即可 关注公众号"Java程序员进阶"回复"vs"也可获取 二. ...

  10. Java对象结构详解【MarkWord 与锁的实现原理】

    Java对象存储在堆(Heap)内存.那么一个 Java对象到底包含什么呢?概括起来分为对象头.对象体和对齐字节.如下图所示: