C#實(shí)現(xiàn)IP代理池調(diào)度的示例代碼
前言
稍微介紹下這個(gè)代碼的用途,在做某些功能的時(shí)候,我們可能會(huì)用到IP代理,購(gòu)買(mǎi)IP的時(shí)候也是可以選擇長(zhǎng)期高質(zhì)量IP或者短失效但量大的IP,這個(gè)主要根據(jù)用途來(lái)購(gòu)買(mǎi);這里就是基于大量短失效IP做的一個(gè)IP調(diào)度,盡可能保證IP能夠物盡其用。
實(shí)現(xiàn)
1.首先定義一個(gè)IPPool類(lèi),然后在構(gòu)造函數(shù)中傳入以下參數(shù)
public class IPPool
{
readonly string _ipUrl, _checkUrl;
readonly int _saveCount;
readonly bool _loopUse;
public ConcurrentQueue<string> IPQueue = new ConcurrentQueue<string>();
/// <summary>
/// 代理IP池
/// </summary>
/// <param name="ipUrl">代理IP的獲取網(wǎng)址</param>
/// <param name="checkUrl">檢查IP可用性的網(wǎng)址</param>
/// <param name="saveCount">IP池的存儲(chǔ)量</param>
/// <param name="loopUse">是否循環(huán)使用</param>
public IPPool(string ipUrl, string checkUrl, int saveCount, bool loopUse=true)
{
_ipUrl = ipUrl;
_checkUrl = checkUrl;
_saveCount = saveCount;
_loopUse = loopUse;
}2.解析網(wǎng)頁(yè)上的IP地址,這里使用虛方法,以方便可以重寫(xiě)解析方法,應(yīng)對(duì)不同的數(shù)據(jù)類(lèi)型
/// <summary>
/// 解析網(wǎng)址IP
/// </summary>
/// <returns></returns>
protected virtual List<string> Parse()
{
List<string> list = new List<string>();
try
{
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 10);
var result = httpClient.GetStringAsync(_ipUrl).Result;
JObject jobj = JObject.Parse(result);
if (jobj["code"].ToString() == "1")
{
JArray jarr = (JArray)jobj["data"];
foreach (var item in jarr)
{
string ip = item["ip"].ToString() + ":" + item["port"].ToString();
list.Add(ip);
}
}
}
catch { }
return list;
}3.檢查IP可用性,這里可以使用你需要訪(fǎng)問(wèn)的網(wǎng)址或者百度進(jìn)行Get,保證可以訪(fǎng)問(wèn)到即可,同樣使用虛方法定義
/// <summary>
/// 檢查IP可用性
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
protected virtual bool Check(string ip)
{
HttpClient httpClient = new HttpClient();
httpClient.Timeout = new TimeSpan(0, 0, 10);
bool result = httpClient.GetAsync(_checkUrl).Result.StatusCode == HttpStatusCode.OK;
return result;
}4.開(kāi)始獲取,使用定時(shí)器獲取,同樣因?yàn)橛性O(shè)置隊(duì)列的最大值,所以只有當(dāng)?shù)陀谶@個(gè)閾值時(shí)才會(huì)進(jìn)行補(bǔ)充,防止IP浪費(fèi)的同時(shí)保證IP充足夠用
/// <summary>
/// 開(kāi)始獲取
/// </summary>
/// <param name="interval">獲取間隔</param>
public virtual void Start(double interval)
{
System.Timers.Timer timer = new System.Timers.Timer(interval);
timer.Elapsed += (s, e) =>
{
if (IPQueue.Count < _saveCount)
{
List<string> list = Parse();
foreach (var ip in list)
{
IPQueue.Enqueue(ip);
}
}
};
timer.Start();
}5.獲取IP,從隊(duì)列中獲取,如果設(shè)置了循環(huán)使用的話(huà),不失效可以一直使用,進(jìn)一步保證IP資源
/// <summary>
/// 獲取IP
/// </summary>
/// <returns></returns>
public virtual string Get()
{
string ip = null;
while (IPQueue.Count > 0)
{
IPQueue.TryPeek(out ip);
if (!string.IsNullOrEmpty(ip)&&Check(ip))
{
if (!_loopUse)
{
IPQueue.TryDequeue(out ip);
}
break;
}
else
{
IPQueue.TryDequeue(out string result);
}
}
??????? return ip;
}
}6.為方便測(cè)試,我們自定義一個(gè)類(lèi)繼承IPPool,然后重寫(xiě)Parse以及Check方法
public IPHelper(string ipUrl, string checkUrl, int saveCount, bool loopUse = true) : base(ipUrl, checkUrl, saveCount,loopUse)
{
??????? }
protected override List<string> Parse()
{
List<string> list = new List<string>();
list.Add(DateTime.Now.Ticks.ToString());
return list;
}
protected override bool Check(string ip)
{
return true;
}7.最后調(diào)用下看看效果
private async void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
IPHelper iPHelper = new IPHelper("", "", 10,false);
iPHelper.Start(200);
for (int i = 0; i < 5; i++)
{
string ip = iPHelper.Get();
if (ip != null)
{
listBox1.Items.Add(ip);
}
await Task.Delay(500);
}
}
??????? private async void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
IPHelper iPHelper = new IPHelper("", "", 10);
iPHelper.Start(200);
for (int i = 0; i < 5; i++)
{
string ip = iPHelper.Get();
if (ip != null)
{
listBox1.Items.Add(ip);
}
await Task.Delay(500);
}
}實(shí)現(xiàn)效果

到此這篇關(guān)于C#實(shí)現(xiàn)IP代理池調(diào)度的示例代碼的文章就介紹到這了,更多相關(guān)C# IP代理池調(diào)度內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- C#實(shí)現(xiàn)單線(xiàn)程異步互斥鎖的示例代碼
- C#單線(xiàn)程和多線(xiàn)程端口掃描器詳解
- C#單線(xiàn)程和多線(xiàn)程的端口掃描器應(yīng)用比較詳解
- 基于C#實(shí)現(xiàn)端口掃描器(單線(xiàn)程和多線(xiàn)程)
- 簡(jiǎn)單對(duì)比C#程序中的單線(xiàn)程與多線(xiàn)程設(shè)計(jì)
- C#線(xiàn)程入門(mén)教程之單線(xiàn)程介紹
- C#實(shí)現(xiàn)Quartz任務(wù)調(diào)度的示例代碼
- C# 并發(fā)控制框架之單線(xiàn)程環(huán)境下實(shí)現(xiàn)每秒百萬(wàn)級(jí)調(diào)度
相關(guān)文章
C#實(shí)現(xiàn)Windows服務(wù)測(cè)試與調(diào)試
這篇文章介紹了C#實(shí)現(xiàn)Windows服務(wù)測(cè)試與調(diào)試的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
C#控件picturebox實(shí)現(xiàn)圖像拖拽和縮放
這篇文章主要為大家詳細(xì)介紹了C#控件picturebox實(shí)現(xiàn)圖像拖拽和縮放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-09-09
C#實(shí)現(xiàn)判斷當(dāng)前操作用戶(hù)管理角色的方法
這篇文章主要介紹了C#實(shí)現(xiàn)判斷當(dāng)前操作用戶(hù)管理角色的方法,涉及C#針對(duì)系統(tǒng)用戶(hù)判斷的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08

