验证URL中GUID值是否重复的类库,防止用户之截刷URL(代码存在问题,一直没找到来。看有没有高人能看出来。)

fjnetphp 2011-04-21 06:32:32
验证URL中GUID值是否重复的类库,防止用户直截刷URL,设计思路如下:

定义了两个队列:

当前写入队列 Hashtable writeTb

备份队列 Hashtable readTb

已经使用过的GUID值记录在writeTb,readTb列表中。

当新的GUID值上来的时候,判断writeTb,readTb队列中是否存在GUID值,如果存在,就判断为非法。

两个队列根据一定的间隔时间来轮换切读写。当readTb切换成写队列的时候。readTb中记录的GUID值全部清除。



直接上代码:(代码是存在问题的,没跑多久的时候CPU就100%了,一直找不到问题,看看有没有高人能看出问题所在)



public class RequestValidate
{
private Thread clearTbWorker = null;
private Hashtable tb1 = new Hashtable(100000);
private Hashtable tb2 = new Hashtable(100000);

/// <summary>
/// 上次转换TB时间
/// </summary>
private DateTime lastSwitchTbTime { get; set; }

/// <summary>
/// 写TB索引
/// </summary>
private int writeTbIndex{get;set;}

/// <summary>
/// 当前写入队列
/// </summary>
private Hashtable writeTb
{
get
{
if (writeTbIndex == 1) return tb1;
else return tb2;
}
}

/// <summary>
/// 备份队列
/// </summary>
private Hashtable readTb
{
get
{
if (writeTbIndex == 1) return tb2;
else return tb1;
}
}

private HttpRequest request { get { return HttpContext.Current.Request; } }

/// <summary>
/// GUID受限使用时间
/// </summary>
private TimeSpan GuidExpiredMinute = TimeSpan.FromMinutes(2);

private RequestValidate()
{
lastSwitchTbTime = System.DateTime.Now;
clearTbWorker = new Thread(new ThreadStart(ClearTbWork));
clearTbWorker.Start();
}

private static RequestValidate instance = null;
public static RequestValidate Instance
{
get
{
if (instance == null)
{
lock (typeof(RequestValidate))
{
if (instance == null)
{
instance = new RequestValidate();
}
}
}
return instance;
}
}

/// <summary>
/// 验证客户端GUID值是否合法
/// </summary>
/// <returns></returns>
public bool Validate()
{
string guid = request["guid"];
if (string.IsNullOrEmpty(guid))
{
#if DEBUG
return false;
#else
return true;
#endif
}

if (!string.IsNullOrEmpty(request["t"]))
{
HttpContext.Current.Response.ContentType = "text/html";
HttpContext.Current.Response.Write("readTb:"+readTb.Count);
HttpContext.Current.Response.Write("writeTb:" + this.writeTb.Count);
HttpContext.Current.Response.End();
}

bool isTrue = true;

try
{
string htKey = guid.ToLower();
if (readTb.ContainsKey(htKey))
{
isTrue = false;
}
else if (writeTb.ContainsKey(htKey))
{
isTrue = false;
}
else
{
writeTb[htKey] = System.DateTime.Now;
}
}
catch (Exception ex)
{
Log.LogComplement.Error(ex);
}

return isTrue;

}

/// <summary>
/// 清除过期队列
/// </summary>
private void ClearTbWork()
{
while (true)
{
try
{


TimeSpan ts = System.DateTime.Now - lastSwitchTbTime;
if (ts < GuidExpiredMinute)
{
System.Threading.Thread.Sleep(ts);
}

//清除GuidExpiredMinute分钟之前备份队列
readTb.Clear();

if (writeTbIndex == 1) writeTbIndex = 2;
else writeTbIndex = 1;

lastSwitchTbTime = System.DateTime.Now;



}
catch (Exception ex)
{
Log.LogComplement.Error(ex);
}
finally
{
System.Threading.Thread.Sleep(GuidExpiredMinute);
}
}

}

}


...全文
20 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧